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

Commit 8be69cf3 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "hal: Fix incall music delivery during voice call issues"

parents 828ab80b ac3db248
Loading
Loading
Loading
Loading
+76 −6
Original line number Diff line number Diff line
@@ -4384,6 +4384,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
    struct audio_device *adev = out->dev;
    ssize_t ret = 0;
    int channels = 0;
    const size_t frame_size = audio_stream_out_frame_size(stream);
    const size_t frames = (frame_size != 0) ? bytes / frame_size : bytes;

    ATRACE_BEGIN("out_write");
    lock_output_stream(out);
@@ -4600,8 +4602,35 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
        return ret;
    } else {
        if (out->pcm) {
            size_t bytes_to_write = bytes;
            if (out->muted)
                memset((void *)buffer, 0, bytes);
            ALOGV("%s: frames=%zu, frame_size=%zu, bytes_to_write=%zu",
                     __func__, frames, frame_size, bytes_to_write);

            if (out->usecase == USECASE_INCALL_MUSIC_UPLINK) {
                size_t channel_count = audio_channel_count_from_out_mask(out->channel_mask);
                int16_t *src = (int16_t *)buffer;
                int16_t *dst = (int16_t *)buffer;

                LOG_ALWAYS_FATAL_IF(out->config.channels != 1 || channel_count != 2 ||
                                    out->format != AUDIO_FORMAT_PCM_16_BIT,
                                    "out_write called for incall music use case with wrong properties");

                /*
                 * FIXME: this can be removed once audio flinger mixer supports
                 * mono output
                 */

                /*
                 * Code below goes over each frame in the buffer and adds both
                 * L and R samples and then divides by 2 to convert to mono
                 */
                for (size_t i = 0; i < frames ; i++, dst++, src += 2) {
                    *dst = (int16_t)(((int32_t)src[0] + (int32_t)src[1]) >> 1);
                }
                bytes_to_write /= 2;
            }

            ALOGVV("%s: writing buffer (%zu bytes) to pcm device", __func__, bytes);

@@ -4611,12 +4640,11 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
                ns = pcm_bytes_to_frames(out->pcm, bytes)*1000000000LL/
                                                     out->config.rate;

            bool use_mmap = is_mmap_usecase(out->usecase) || out->realtime;

            request_out_focus(out, ns);
            bool use_mmap = is_mmap_usecase(out->usecase) || out->realtime;

            if (use_mmap)
                ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes);
                ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes_to_write);
            else if (out->hal_op_format != out->hal_ip_format &&
                       out->convert_buffer != NULL) {

@@ -4650,7 +4678,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
                           out_get_sample_rate(&out->stream.common));
                    ret = 0;
                } else
                    ret = pcm_write(out->pcm, (void *)buffer, bytes);
                    ret = pcm_write(out->pcm, (void *)buffer, bytes_to_write);
            }

            release_out_focus(out);
@@ -6166,6 +6194,48 @@ int adev_open_output_stream(struct audio_hw_device *dev,
        create_offload_callback_thread(out);

    } else if (out->flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) {
          switch (config->sample_rate) {
            case 0:
                out->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
                break;
            case 8000:
            case 16000:
            case 48000:
                out->sample_rate = config->sample_rate;
                break;
            default:
                ALOGE("%s: Unsupported sampling rate %d for Incall Music", __func__,
                      config->sample_rate);
                config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
                ret = -EINVAL;
                goto error_open;
        }
        //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
        switch (config->channel_mask) {
            case AUDIO_CHANNEL_NONE:
            case AUDIO_CHANNEL_OUT_STEREO:
                out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
                break;
            default:
                ALOGE("%s: Unsupported channel mask %#x for Incall Music", __func__,
                      config->channel_mask);
                config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
                ret = -EINVAL;
                goto error_open;
        }
        switch (config->format) {
            case AUDIO_FORMAT_DEFAULT:
            case AUDIO_FORMAT_PCM_16_BIT:
                out->format = AUDIO_FORMAT_PCM_16_BIT;
                break;
            default:
                ALOGE("%s: Unsupported format %#x for Incall Music", __func__,
                      config->format);
                config->format = AUDIO_FORMAT_PCM_16_BIT;
                ret = -EINVAL;
                goto error_open;
        }

        ret = voice_extn_check_and_set_incall_music_usecase(adev, out);
        if (ret != 0) {
            ALOGE("%s: Incall music delivery usecase cannot be set error:%d",
+7 −18
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
 * Not a contribution.
 *
 * Copyright (C) 2013 The Android Open Source Project
@@ -593,27 +593,16 @@ void voice_extn_in_get_parameters(struct stream_in *in,
    voice_extn_compress_voip_in_get_parameters(in, query, reply);
}

#ifdef INCALL_MUSIC_ENABLED
int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
                                                  struct stream_out *out)
{
    uint32_t session_id = 0;

    session_id = get_session_id_with_state(adev, CALL_LOCAL_HOLD);
    if (session_id == VOICE_VSID) {
    out->usecase = USECASE_INCALL_MUSIC_UPLINK;
    } else if (session_id == VOICE2_VSID) {
        out->usecase = USECASE_INCALL_MUSIC_UPLINK2;
    } else {
        ALOGE("%s: Invalid session id %x", __func__, session_id);
        return -EINVAL;
    }

    out->config = pcm_config_incall_music;
    out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
    out->channel_mask = AUDIO_CHANNEL_OUT_MONO;
    //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
    out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
    out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
    out->config.rate = out->sample_rate;

    ALOGV("%s: mode=%d, usecase id=%d", __func__, adev->mode, out->usecase);
    return 0;
}
#endif
+1 −6
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2014, 2016-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2014, 2016-2018, The Linux Foundation. All rights reserved.
 * Not a contribution.
 *
 * Copyright (C) 2013 The Android Open Source Project
@@ -101,13 +101,8 @@ static void __unused voice_extn_out_get_parameters(struct stream_out *out __unus
}
#endif

#ifdef INCALL_MUSIC_ENABLED
int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
                                                  struct stream_out *out);
#else
#define voice_extn_check_and_set_incall_music_usecase(adev, out) -ENOSYS
#endif

#ifdef COMPRESS_VOIP_ENABLED
int voice_extn_compress_voip_close_output_stream(struct audio_stream *stream);
int voice_extn_compress_voip_open_output_stream(struct stream_out *out);