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

Commit 21e45917 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "audio: Add HiFi Filter support"

parents e0e369fb ab51d045
Loading
Loading
Loading
Loading
+82 −0
Original line number Diff line number Diff line
@@ -192,6 +192,7 @@ static bool audio_extn_compress_in_enabled = false;
static bool audio_extn_battery_listener_enabled = false;
static bool audio_extn_maxx_audio_enabled = false;
static bool audio_extn_audiozoom_enabled = false;
static bool audio_extn_hifi_filter_enabled = false;

#define AUDIO_PARAMETER_KEY_AANC_NOISE_LEVEL "aanc_noise_level"
#define AUDIO_PARAMETER_KEY_ANC        "anc_enabled"
@@ -5203,6 +5204,87 @@ bool audio_extn_battery_properties_is_charging()
}
// END: BATTERY_LISTENER ================================================================

// START: HiFi Filter Feature ============================================================
void audio_extn_enable_hifi_filter(struct audio_device *adev, bool value)
{
    const char *mixer_ctl_name = "HiFi Filter";
    struct mixer_ctl *ctl = NULL;
    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
    if (!ctl) {
        ALOGE("%s: Could not get ctl for mixer cmd - %s, using default control",
              __func__, mixer_ctl_name);
        return;
    } else {
        mixer_ctl_set_value(ctl, 0, value);
        ALOGD("%s: mixer_value set %d", __func__, value);
    }
    return;
}

void audio_extn_hifi_filter_set_params(struct str_parms *parms,
                                        char *value, int len)
{
    int ret = 0;
    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HIFI_AUDIO_FILTER, value,len);
    if (ret >= 0) {
        if (value && !strncmp(value, "true", sizeof("true")))
            audio_extn_hifi_filter_enabled = true;
        else
            audio_extn_hifi_filter_enabled = false;
        str_parms_del(parms, AUDIO_PARAMETER_KEY_HIFI_AUDIO_FILTER);
    }
}

bool audio_extn_hifi_check_usecase_params(int sample_rate, int usecase)
{
    if (sample_rate != 48000 && sample_rate != 44100)
        return false;
    if (usecase == USECASE_AUDIO_PLAYBACK_LOW_LATENCY || usecase == USECASE_AUDIO_PLAYBACK_ULL)
        return false;
    return true;
}

bool audio_extn_is_hifi_filter_enabled(struct audio_device* adev, struct stream_out *out,
                                   snd_device_t snd_device, char *codec_variant,
                                   int channels, int usecase_init)
{
    int na_mode = platform_get_native_support();
    struct audio_usecase *uc = NULL;
    struct listnode *node = NULL;
    bool hifi_active = false;

    if (audio_extn_hifi_filter_enabled) {
        /*Restricting the feature for Tavil and WCD9375 codecs only*/
        if ((strstr(codec_variant, "WCD9385") || strstr(codec_variant, "WCD9375"))
            && (na_mode == NATIVE_AUDIO_MODE_MULTIPLE_MIX_IN_DSP) && channels <=2) {
            /*Upsampling 8 time should be restricited to headphones playback only */
            if (snd_device == SND_DEVICE_OUT_HEADPHONES
                || snd_device == SND_DEVICE_OUT_HEADPHONES_44_1
                || snd_device == SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER
                || usecase_init) {
                if (audio_extn_hifi_check_usecase_params(out->sample_rate,
                    out->usecase) && !usecase_init)
                    return true;

                list_for_each(node, &adev->usecase_list) {
                    /* checking if hifi_filter is already active to set */
                    /* concurrent playback sessions with hifi_filter enabled*/
                    uc = node_to_item(node, struct audio_usecase, list);
                    struct stream_out *curr_out = (struct stream_out*) uc->stream.out;
                    if (uc->type == PCM_PLAYBACK && curr_out
                        && audio_extn_hifi_check_usecase_params(
                        curr_out->sample_rate, curr_out->usecase) &&
                        (curr_out->channel_mask == AUDIO_CHANNEL_OUT_STEREO ||
                        curr_out->channel_mask == AUDIO_CHANNEL_OUT_MONO))
                            hifi_active = true;
                }
            }
        }
    }
    return hifi_active;
}
// END: HiFi Filter Feature ==============================================================

// START: AUDIOZOOM_FEATURE =====================================================================
#ifdef __LP64__
#define AUDIOZOOM_LIB_PATH "/vendor/lib64/libaudiozoom.so"
+10 −0
Original line number Diff line number Diff line
@@ -117,6 +117,8 @@ int audio_extn_parse_compress_metadata(struct stream_out *out,
#define MAX_LENGTH_MIXER_CONTROL_IN_INT                  (128)
#define HW_INFO_ARRAY_MAX_SIZE 32

#define AUDIO_PARAMETER_KEY_HIFI_AUDIO_FILTER "hifi_filter"

struct snd_card_split {
    char device[HW_INFO_ARRAY_MAX_SIZE];
    char snd_card[HW_INFO_ARRAY_MAX_SIZE];
@@ -262,6 +264,14 @@ int32_t audio_extn_read_afe_proxy_channel_masks(struct stream_out *out);
int32_t audio_extn_get_afe_proxy_channel_count();
//END: AFE_PROXY_FEATURE

//START: HIFI FILTER
void audio_extn_enable_hifi_filter(struct audio_device *adev, bool value);
void audio_extn_hifi_filter_set_params(struct str_parms *parms, char *value, int len);
bool audio_extn_is_hifi_filter_enabled(struct audio_device* adev,struct stream_out *out,
                                   snd_device_t snd_device, char *codec_variant,
                                   int channels, int usecase_init);
//END: HIFI FILTER

/// ---- USB feature ---------------------------------------------------------------
void audio_extn_usb_init(void *adev);
void audio_extn_usb_deinit();
+2 −1
Original line number Diff line number Diff line
@@ -64,7 +64,8 @@ static const snd_device_t wsa_combo_devices[] = {
    SND_DEVICE_OUT_SPEAKER_AND_LINE,
    SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1,
    SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2,
    SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET
    SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
    SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_HIFI_FILTER
};

static const snd_device_t taiko_fluid_variant_devices[] = {
+69 −2
Original line number Diff line number Diff line
@@ -507,6 +507,8 @@ static const char * const device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
    [SND_DEVICE_OUT_HEADPHONES] = "headphones",
    [SND_DEVICE_OUT_HEADPHONES_DSD] = "headphones-dsd",
    [SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER] = "headphones-hifi-filter",
    [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_HIFI_FILTER] = "speaker-and-headphones-hifi-filter",
    [SND_DEVICE_OUT_HEADPHONES_44_1] = "headphones-44.1",
    [SND_DEVICE_OUT_LINE] = "line",
    [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
@@ -844,6 +846,8 @@ static int acdb_device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_OUT_TRANSMISSION_FM] = 0,
    [SND_DEVICE_OUT_ANC_HEADSET] = 26,
    [SND_DEVICE_OUT_ANC_FB_HEADSET] = 27,
    [SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER] = 188,
    [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_HIFI_FILTER] = 188,
    [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = 26,
    [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = 27,
    [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = 26,
@@ -1014,6 +1018,8 @@ static struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_DSD)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_HIFI_FILTER)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_44_1)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
@@ -2160,6 +2166,9 @@ static void set_platform_defaults(struct platform_data * my_data)
    backend_tag_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("capture-fm");
    backend_tag_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
    backend_tag_table[SND_DEVICE_OUT_HEADPHONES_DSD] = strdup("headphones-dsd");
    backend_tag_table[SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER] = strdup("headphones-hifi-filter");
    backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_HIFI_FILTER] =
        strdup("speaker-and-headphones-hifi-filter");
    backend_tag_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
    backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("voice-speaker-vbat");
    backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_2_VBAT] = strdup("voice-speaker-2-vbat");
@@ -4935,6 +4944,9 @@ int platform_get_backend_index(snd_device_t snd_device)
                if (strncmp(backend_tag_table[snd_device], "headphones-44.1",
                            sizeof("headphones-44.1")) == 0)
                        port = HEADPHONE_44_1_BACKEND;
                else if (strncmp(backend_tag_table[snd_device], "headphones-hifi-filter",
                            sizeof("headphones-hifi-filter")) == 0)
                        port = HEADPHONE_BACKEND;
                else if (strncmp(backend_tag_table[snd_device], "headphones-dsd",
                            sizeof("headphones-dsd")) == 0)
                        port = DSD_NATIVE_BACKEND;
@@ -5607,6 +5619,12 @@ int platform_split_snd_device(void *platform,
        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
        new_snd_devices[1] = SND_DEVICE_OUT_USB_HEADSET;
        ret = 0;
    } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_HIFI_FILTER &&
               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER)) {
        *num_devices = 2;
        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
        new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER;
        ret = 0;
    } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_BT_SCO &&
               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_BT_SCO)) {
        *num_devices = 2;
@@ -5905,6 +5923,9 @@ snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *o
                snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2;
            else if (is_active_voice_call)
                snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES;
            else if  (audio_extn_is_hifi_filter_enabled(adev, out, snd_device,
               my_data->codec_variant, channel_count, 1))
                snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_HIFI_FILTER;
            else
                snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
        } else if (devices == (AUDIO_DEVICE_OUT_LINE |
@@ -5928,6 +5949,9 @@ snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *o
                snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1;
            else if (my_data->external_spk_2)
                snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2;
            else if  (audio_extn_is_hifi_filter_enabled(adev, out, snd_device,
               my_data->codec_variant, channel_count, 1))
                snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_HIFI_FILTER;
            else {
                if (is_active_voice_call)
                    snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES;
@@ -6196,6 +6220,11 @@ snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *o
                snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
        } else if (out->format == AUDIO_FORMAT_DSD) {
                snd_device = SND_DEVICE_OUT_HEADPHONES_DSD;
        } else if (audio_extn_is_hifi_filter_enabled(adev, out, snd_device,
             my_data->codec_variant, channel_count, 1)) {
                snd_device = SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER;
        } else if (devices & SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER) {
                snd_device = SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER;
        } else if (devices & AUDIO_DEVICE_OUT_LINE) {
                snd_device = SND_DEVICE_OUT_LINE;
        } else
@@ -7429,7 +7458,7 @@ static void true_32_bit_set_params(struct str_parms *parms,
    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TRUE_32_BIT,
                            value,len);
    if (ret >= 0) {
        if (value && !strncmp(value, "true", sizeof("src")))
        if (value && !strncmp(value, "true", sizeof("true")))
            supports_true_32_bit = true;
        else
            supports_true_32_bit = false;
@@ -7779,6 +7808,7 @@ int platform_set_parameters(void *platform, struct str_parms *parms)
    audio_extn_hfp_set_parameters(my_data->adev, parms);
    perf_lock_set_params(platform, parms, value, len);
    true_32_bit_set_params(parms, value, len);
    audio_extn_hifi_filter_set_params(parms, value, len);
    platform_spkr_device_set_params(platform, parms, value, len);
done:
    ALOGV("%s: exit with code(%d)", __func__, ret);
@@ -8944,6 +8974,12 @@ static bool platform_check_codec_backend_cfg(struct audio_device* adev,
                        if (channels < out_channels)
                            channels = out_channels;
                }
                if ((snd_device == SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER) &&
                    (usecase->id==USECASE_AUDIO_PLAYBACK_LOW_LATENCY ||
                      usecase->id == USECASE_AUDIO_PLAYBACK_ULL)) {
                       sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
                       bit_width = my_data->current_backend_cfg[backend_idx].bit_width;
                }
            }
        }
    }
@@ -9043,6 +9079,37 @@ static bool platform_check_codec_backend_cfg(struct audio_device* adev,
        }
    }

    if (backend_idx != platform_get_voice_call_backend(adev)
        && usecase->type == PCM_PLAYBACK) {
        struct stream_out *out = (struct stream_out*) usecase->stream.out;
        if(audio_extn_is_hifi_filter_enabled(adev, out, snd_device,
            my_data->codec_variant, channels, 0))  {
            switch (sample_rate) {
                case 48000:
                    audio_extn_enable_hifi_filter(adev, true);
                    if (audio_is_true_native_stream_active(adev))
                        sample_rate = 352800;
                    else
                        sample_rate = 384000;
                    bit_width = 32;
                    break;
                case 44100:
                    audio_extn_enable_hifi_filter(adev, true);
                    sample_rate = 352800;
                    bit_width = 32;
                    break;
                default:
                    audio_extn_enable_hifi_filter(adev, false);
            }
        }
        if (snd_device != SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER)
            audio_extn_enable_hifi_filter(adev, false);
        ALOGD("%s:becf: updated afe: bitwidth %d, samplerate %d channels %d,"
            "backend_idx %d usecase = %d device (%s)", __func__, bit_width,
            sample_rate, channels, backend_idx, usecase->id,
            platform_get_snd_device_name(snd_device));
    }

    /*
     * Handset and speaker may have diffrent backend. Check if the device is speaker or handset,
     * and these devices are restricited to 48kHz.
@@ -9165,7 +9232,7 @@ static bool platform_check_codec_backend_cfg(struct audio_device* adev,
    }

    if (snd_device == SND_DEVICE_OUT_HEADPHONES || snd_device ==
        SND_DEVICE_OUT_HEADPHONES_44_1) {
        SND_DEVICE_OUT_HEADPHONES_44_1 || snd_device == SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER) {
        if (sample_rate > 48000 ||
            (bit_width >= 24 && (sample_rate == 48000  || sample_rate == 44100))) {
            ALOGI("%s: apply HPH HQ mode\n", __func__);
+2 −0
Original line number Diff line number Diff line
@@ -92,8 +92,10 @@ enum {
    SND_DEVICE_OUT_LINE,
    SND_DEVICE_OUT_HEADPHONES,
    SND_DEVICE_OUT_HEADPHONES_DSD,
    SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER,
    SND_DEVICE_OUT_HEADPHONES_44_1,
    SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
    SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_HIFI_FILTER,
    SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES,
    SND_DEVICE_OUT_SPEAKER_AND_LINE,
    SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE,