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

Commit cb6212e0 authored by Preetam Singh Ranawat's avatar Preetam Singh Ranawat Committed by Gerrit - the friendly Code Review server
Browse files

hal: Add support for native-DSD and native sampling rates

 -set passthrough flag and diable gapless for native dsd
 -Select new backend for native dsd.
 -Add support for e2e playback of clips with sampling rate
  multiple of 44.1.

Change-Id: I6aa0ef5ea176a0923b0b88924ab046f9a11b7b12
parent db96a594
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -401,6 +401,10 @@ void audio_extn_dolby_send_ddp_endp_params(struct audio_device *adev);

#endif

#ifndef AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
#define AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH  0x10000
#endif

#ifndef HDMI_PASSTHROUGH_ENABLED
#define audio_extn_passthru_update_stream_configuration(adev, out)            (0)
#define audio_extn_passthru_is_convert_supported(adev, out)                   (0)
@@ -419,8 +423,6 @@ void audio_extn_dolby_send_ddp_endp_params(struct audio_device *adev);
#define audio_extn_passthru_set_parameters(a, p) (-ENOSYS)
#define audio_extn_passthru_init(a) do {} while(0)
#define audio_extn_passthru_should_standby(o) (1)

#define AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH  0x1000
#else
bool audio_extn_passthru_is_convert_supported(struct audio_device *adev,
                                                 struct stream_out *out);
+16 −2
Original line number Diff line number Diff line
@@ -90,9 +90,7 @@ const struct string_to_enum s_flag_name_to_enum_table[] = {
#ifdef INCALL_MUSIC_ENABLED
    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_INCALL_MUSIC),
#endif
#ifdef HDMI_PASSTHROUGH_ENABLED
    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH),
#endif
};

const struct string_to_enum s_format_name_to_enum_table[] = {
@@ -133,6 +131,7 @@ const struct string_to_enum s_format_name_to_enum_table[] = {
    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_LC),
    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_HE_V1),
    STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_HE_V2),
    STRING_TO_ENUM(AUDIO_FORMAT_DSD),
#endif
};

@@ -515,6 +514,21 @@ void audio_extn_utils_update_stream_app_type_cfg(void *platform,
                               __func__, sample_rate);
        }
    }

    /* Set sampling rate to 176.4 for DSD64
     * and 352.8Khz for DSD128.
     * Set Bit Width to 16. output will be 16 bit
     * post DoP in ASM.
     */
    if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH) &&
        (format == AUDIO_FORMAT_DSD)) {
        bit_width = 16;
        if (sample_rate == INPUT_SAMPLING_RATE_DSD64)
            sample_rate = OUTPUT_SAMPLING_RATE_DSD64;
        else if (sample_rate == INPUT_SAMPLING_RATE_DSD128)
            sample_rate = OUTPUT_SAMPLING_RATE_DSD128;
    }

    ALOGV("%s: flags: %x, format: %x sample_rate %d",
           __func__, flags, format, sample_rate);
    list_for_each(node_i, streams_output_cfg_list) {
+65 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@
/* ToDo: Check and update a proper value in msec */
#define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 50
#define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000
#define DSD_VOLUME_MIN_DB (-110)

#define PROXY_OPEN_RETRY_COUNT           100
#define PROXY_OPEN_WAIT_TIME             20
@@ -501,6 +502,7 @@ static bool is_supported_format(audio_format_t format)
        format == AUDIO_FORMAT_FLAC ||
        format == AUDIO_FORMAT_ALAC ||
        format == AUDIO_FORMAT_APE ||
        format == AUDIO_FORMAT_DSD ||
        format == AUDIO_FORMAT_VORBIS ||
        format == AUDIO_FORMAT_WMA ||
        format == AUDIO_FORMAT_WMA_PRO)
@@ -541,6 +543,9 @@ static int get_snd_codec_id(audio_format_t format)
    case AUDIO_FORMAT_APE:
        id = SND_AUDIOCODEC_APE;
        break;
    case AUDIO_FORMAT_DSD:
        id = SND_AUDIOCODEC_DSD;
        break;
    case AUDIO_FORMAT_VORBIS:
        id = SND_AUDIOCODEC_VORBIS;
        break;
@@ -1166,6 +1171,28 @@ exit:
    return active;
}

/*
 * if native DSD playback active
 */
bool audio_is_dsd_native_stream_active(struct audio_device *adev)
{
    bool active = false;
    struct listnode *node = NULL;
    struct audio_usecase *uc = NULL;
    struct stream_out *curr_out = NULL;

    list_for_each(node, &adev->usecase_list) {
        uc = node_to_item(node, struct audio_usecase, list);
        curr_out = (struct stream_out*) uc->stream.out;

        if (curr_out && PCM_PLAYBACK == uc->type &&
               (DSD_NATIVE_BACKEND == platform_get_backend_index(uc->out_snd_device))) {
            active = true;
            ALOGV("%s:DSD playback is active", __func__);
        }
    }
    return active;
}

static bool force_device_switch(struct audio_usecase *usecase)
{
@@ -2537,6 +2564,14 @@ static uint32_t out_get_latency(const struct audio_stream_out *stream)
    return latency;
}

static float AmpToDb(float amplification)
{
    if (amplification == 0) {
        return DSD_VOLUME_MIN_DB;
    }
    return 20 * log10(amplification);
}

static int out_set_volume(struct audio_stream_out *stream, float left,
                          float right)
{
@@ -2555,6 +2590,20 @@ static int out_set_volume(struct audio_stream_out *stream, float left,
             * Mute is 0 and unmute 1
             */
            audio_extn_passthru_set_volume(out, (left == 0.0f));
        } else if (out->format == AUDIO_FORMAT_DSD){
            char mixer_ctl_name[128] =  "DSD Volume";
            struct audio_device *adev = out->dev;
            struct mixer_ctl *ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);

            if (!ctl) {
                ALOGE("%s: Could not get ctl for mixer cmd - %s",
                      __func__, mixer_ctl_name);
                return -EINVAL;
            }
            volume[0] = (int)(AmpToDb(left));
            volume[1] = (int)(AmpToDb(right));
            mixer_ctl_set_array(ctl, volume, sizeof(volume)/sizeof(volume[0]));
            return 0;
        } else {
            char mixer_ctl_name[128];
            struct audio_device *adev = out->dev;
@@ -3666,12 +3715,24 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
                __func__, config->offload_info.version,
                config->offload_info.bit_rate);

        /*Check if DSD audio format is supported in codec
         *and there is no active native DSD use case
         */

        if ((config->format == AUDIO_FORMAT_DSD) &&
               (!platform_check_codec_dsd_support(adev->platform) ||
               audio_is_dsd_native_stream_active(adev))) {
            ret = -EINVAL;
            goto error_open;
        }

        /* Disable gapless if any of the following is true
         * passthrough playback
         * AV playback
         * Direct PCM playback
         */
        if (audio_extn_passthru_is_passthrough_stream(out) ||
            (config->format == AUDIO_FORMAT_DSD) ||
            config->offload_info.has_video ||
            out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
            check_and_set_gapless_mode(adev, false);
@@ -3681,6 +3742,10 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
        if (audio_extn_passthru_is_passthrough_stream(out)) {
            out->flags |= AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH;
        }
        if (config->format == AUDIO_FORMAT_DSD) {
            out->flags |= AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH;
            out->compr_config.codec->compr_passthr = PASSTHROUGH_DSD;
        }
    } else if (out->flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) {
        ret = voice_extn_check_and_set_incall_music_usecase(adev, out);
        if (ret != 0) {
+1 −0
Original line number Diff line number Diff line
@@ -410,6 +410,7 @@ bool is_offload_usecase(audio_usecase_t uc_id);

bool audio_is_true_native_stream_active(struct audio_device *adev);

bool audio_is_dsd_native_stream_active(struct audio_device *adev);
int pcm_ioctl(struct pcm *pcm, int request, ...);

int get_snd_card_state(struct audio_device *adev);
+6 −1
Original line number Diff line number Diff line
@@ -2448,7 +2448,7 @@ int check_44100_support_device(audio_devices_t out_device)
    return ret;
}

static int platform_get_backend_index(snd_device_t snd_device)
int platform_get_backend_index(snd_device_t snd_device)
{
    int32_t port = DEFAULT_CODEC_BACKEND;

@@ -5408,3 +5408,8 @@ int platform_set_sidetone(struct audio_device *adev,
    }
    return 0;
}

bool platform_check_codec_dsd_support(void *platform __unused)
{
    return false;
}
Loading