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

Commit 09c8ed9e authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge 8b0868f1 on remote branch

Change-Id: I83e699fc0549cece6aa42b3b427dd876910789bc
parents 95ddb443 8b0868f1
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -1294,6 +1294,12 @@ static int32_t afe_proxy_set_channel_mapping(struct audio_device *adev,
        set_values[0] = PCM_CHANNEL_FL;
        set_values[1] = PCM_CHANNEL_FR;
        break;
     case 4:
        set_values[0] = PCM_CHANNEL_FL;
        set_values[1] = PCM_CHANNEL_FR;
        set_values[2] = PCM_CHANNEL_LS;
        set_values[3] = PCM_CHANNEL_LFE;
        break;
    case 6:
        set_values[0] = PCM_CHANNEL_FL;
        set_values[1] = PCM_CHANNEL_FR;
@@ -1390,7 +1396,7 @@ int32_t audio_extn_set_afe_proxy_channel_mixer(struct audio_device *adev,
    }
    mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);

    if (channel_count == 6 || channel_count == 8 || channel_count == 2) {
    if (channel_count == 6 || channel_count == 8 || channel_count == 2 || channel_count == 4) {
        ret = afe_proxy_set_channel_mapping(adev, channel_count, snd_device);
    } else {
        ALOGE("%s: set unsupported channel count(%d)",  __func__, channel_count);
+118 −90
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2013 The Android Open Source Project
@@ -102,6 +102,7 @@
#define INVALID_OUT_VOLUME -1
#define AUDIO_IO_PORTS_MAX 32

#define PLAYBACK_GAIN_MAX 1.0f
#define RECORD_GAIN_MIN 0.0f
#define RECORD_GAIN_MAX 1.0f
#define RECORD_VOLUME_CTL_MAX 0x2000
@@ -1227,16 +1228,11 @@ int enable_audio_route(struct audio_device *adev,
    if (audio_extn_is_maxx_audio_enabled())
        audio_extn_ma_set_device(usecase);
    audio_extn_utils_send_audio_calibration(adev, usecase);
    if ((usecase->type == PCM_PLAYBACK) &&
            ((out = usecase->stream.out) != NULL)) {
        if (!is_offload_usecase(out->usecase)) {
            pthread_mutex_lock(&out->latch_lock);
            out->muted = false;
            pthread_mutex_unlock(&out->latch_lock);
        } else if (out->compr) {
    if ((usecase->type == PCM_PLAYBACK) && is_offload_usecase(usecase->id)) {
        out = usecase->stream.out;
        if (out && out->compr)
            audio_extn_utils_compress_set_clk_rec_mode(usecase);
    }
    }

    if (usecase->type == PCM_CAPTURE) {
        in = usecase->stream.in;
@@ -2987,6 +2983,30 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
    }
    enable_audio_route(adev, usecase);

    if (uc_id == USECASE_AUDIO_PLAYBACK_VOIP) {
        struct stream_in *voip_in = get_voice_communication_input(adev);
        struct audio_usecase *voip_in_usecase = NULL;
        voip_in_usecase = get_usecase_from_list(adev, USECASE_AUDIO_RECORD_VOIP);
        if (voip_in != NULL &&
            voip_in_usecase != NULL &&
            !(out_snd_device == AUDIO_DEVICE_OUT_SPEAKER ||
              out_snd_device == AUDIO_DEVICE_OUT_SPEAKER_SAFE) &&
            (voip_in_usecase->in_snd_device ==
            platform_get_input_snd_device(adev->platform, voip_in,
                    &usecase->stream.out->device_list,usecase->type))) {
            /*
             * if VOIP TX is enabled before VOIP RX, needs to re-route the TX path
             * for enabling echo-reference-voip with correct port
             */
            ALOGD("%s: VOIP TX is enabled before VOIP RX,needs to re-route the TX path",__func__);
            disable_audio_route(adev, voip_in_usecase);
            disable_snd_device(adev, voip_in_usecase->in_snd_device);
            enable_snd_device(adev, voip_in_usecase->in_snd_device);
            enable_audio_route(adev, voip_in_usecase);
        }
    }


    audio_extn_qdsp_set_device(usecase);

    /* If input stream is already running then effect needs to be
@@ -3351,10 +3371,12 @@ static int send_offload_cmd_l(struct stream_out* out, int command)
    return 0;
}

/* must be called with out->lock and latch lock */
/* must be called with out->lock */
static void stop_compressed_output_l(struct stream_out *out)
{
    pthread_mutex_lock(&out->latch_lock);
    out->offload_state = OFFLOAD_STATE_IDLE;
    pthread_mutex_unlock(&out->latch_lock);
    out->playback_started = 0;
    out->send_new_metadata = 1;
    if (out->compr != NULL) {
@@ -3612,11 +3634,9 @@ static int create_offload_callback_thread(struct stream_out *out)
static int destroy_offload_callback_thread(struct stream_out *out)
{
    lock_output_stream(out);
    pthread_mutex_lock(&out->latch_lock);
    stop_compressed_output_l(out);
    send_offload_cmd_l(out, OFFLOAD_CMD_EXIT);

    pthread_mutex_unlock(&out->latch_lock);
    pthread_mutex_unlock(&out->lock);
    pthread_join(out->offload_thread, (void **) NULL);
    pthread_cond_destroy(&out->offload_cond);
@@ -3641,6 +3661,8 @@ static int stop_output_stream(struct stream_out *out)
        return -EINVAL;
    }

    out->a2dp_muted = false;

    if (audio_extn_ext_hw_plugin_usecase_stop(adev->ext_hw_plugin, uc_info))
        ALOGE("%s: failed to stop ext hw plugin", __func__);

@@ -3689,9 +3711,6 @@ static int stop_output_stream(struct stream_out *out)

    list_remove(&uc_info->list);
    out->started = 0;
    pthread_mutex_lock(&out->latch_lock);
    out->muted = false;
    pthread_mutex_unlock(&out->latch_lock);
    if (is_offload_usecase(out->usecase) &&
        (audio_extn_passthru_is_passthrough_stream(out))) {
        ALOGV("Disable passthrough , reset mixer to pcm");
@@ -3827,7 +3846,7 @@ int start_output_stream(struct stream_out *out)
            if (is_speaker_active || is_speaker_safe_active) {
                a2dp_combo = true;
            } else {
                if (!(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
                if (!is_offload_usecase(out->usecase)) {
                    ALOGE("%s: A2DP profile is not ready, return error", __func__);
                    ret = -EAGAIN;
                    goto error_config;
@@ -4512,9 +4531,7 @@ static int out_standby(struct audio_stream *stream)
            adev->adm_deregister_stream(adev->adm_data, out->handle);

        if (is_offload_usecase(out->usecase)) {
            pthread_mutex_lock(&out->latch_lock);
            stop_compressed_output_l(out);
            pthread_mutex_unlock(&out->latch_lock);
        }

        pthread_mutex_lock(&adev->lock);
@@ -4589,9 +4606,7 @@ static int out_on_error(struct audio_stream *stream)
    // is needed e.g. when SSR happens within compress_open
    // since the stream is active, offload_callback_thread is also active.
    if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
        pthread_mutex_lock(&out->latch_lock);
        stop_compressed_output_l(out);
        pthread_mutex_unlock(&out->latch_lock);
    }
    pthread_mutex_unlock(&out->lock);

@@ -4630,9 +4645,7 @@ int out_standby_l(struct audio_stream *stream)
            adev->adm_deregister_stream(adev->adm_data, out->handle);

        if (is_offload_usecase(out->usecase)) {
            pthread_mutex_lock(&out->latch_lock);
            stop_compressed_output_l(out);
            pthread_mutex_unlock(&out->latch_lock);
        }

        out->standby = true;
@@ -4979,17 +4992,19 @@ int route_output_stream(struct stream_out *out,
                platform_set_swap_channels(adev, true);
                audio_extn_perf_lock_release(&adev->perf_lock_handle);
            }
            if ((out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
                 (!is_a2dp_out_device_type(&out->device_list) || audio_extn_a2dp_source_is_ready())) {
            pthread_mutex_lock(&out->latch_lock);
                if (out->a2dp_compress_mute) {
                    out->a2dp_compress_mute = false;
            if (!is_a2dp_out_device_type(&out->device_list) || audio_extn_a2dp_source_is_ready()) {
                if (out->a2dp_muted) {
                    out->a2dp_muted = false;
                    if (is_offload_usecase(out->usecase))
                        out_set_compr_volume(&out->stream, out->volume_l, out->volume_r);
                    else if (out->usecase != USECASE_AUDIO_PLAYBACK_VOIP)
                        out_set_pcm_volume(&out->stream, out->volume_l, out->volume_r);
                }
                pthread_mutex_unlock(&out->latch_lock);
            } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
                out_set_voip_volume(&out->stream, out->volume_l, out->volume_r);
            }
            if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP && !out->a2dp_muted)
                out_set_voip_volume(&out->stream, out->volume_l, out->volume_r);
            pthread_mutex_unlock(&out->latch_lock);
        }
    }

@@ -5541,9 +5556,7 @@ static int out_set_volume(struct audio_stream_out *stream, float left,
    ALOGD("%s: called with left_vol=%f, right_vol=%f", __func__, left, right);
    if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
        /* only take left channel into account: the API is for stereo anyway */
        pthread_mutex_lock(&out->latch_lock);
        out->muted = (left == 0.0f);
        pthread_mutex_unlock(&out->latch_lock);
        return 0;
    } else if (is_offload_usecase(out->usecase)) {
        if (audio_extn_passthru_is_passthrough_stream(out)) {
@@ -5581,15 +5594,15 @@ static int out_set_volume(struct audio_stream_out *stream, float left,
                }
            }
            pthread_mutex_lock(&out->latch_lock);
            if (!out->a2dp_compress_mute) {
            if (!out->a2dp_muted) {
                ret = out_set_compr_volume(&out->stream, out->volume_l, out->volume_r);
            }
            pthread_mutex_unlock(&out->latch_lock);
            return ret;
        } else {
            pthread_mutex_lock(&out->latch_lock);
            ALOGV("%s: compress mute %d", __func__, out->a2dp_compress_mute);
            if (!out->a2dp_compress_mute)
            ALOGV("%s: compress mute %d", __func__, out->a2dp_muted);
            if (!out->a2dp_muted)
                ret = out_set_compr_volume(stream, left, right);
            out->volume_l = left;
            out->volume_r = right;
@@ -5599,14 +5612,17 @@ static int out_set_volume(struct audio_stream_out *stream, float left,
    } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
        out->app_type_cfg.gain[0] = (int)(left * VOIP_PLAYBACK_VOLUME_MAX);
        out->app_type_cfg.gain[1] = (int)(right * VOIP_PLAYBACK_VOLUME_MAX);
        pthread_mutex_lock(&out->latch_lock);
        if (!out->standby) {
            audio_extn_utils_send_app_type_gain(out->dev,
                                                out->app_type_cfg.app_type,
                                                &out->app_type_cfg.gain[0]);
            if (!out->a2dp_muted)
                ret = out_set_voip_volume(stream, left, right);
        }
        out->volume_l = left;
        out->volume_r = right;
        pthread_mutex_unlock(&out->latch_lock);
        return ret;
    } else if (out->usecase == USECASE_AUDIO_PLAYBACK_MMAP) {
        ALOGV("%s: MMAP set volume called", __func__);
@@ -5618,21 +5634,25 @@ static int out_set_volume(struct audio_stream_out *stream, float left,
    } else if (out->usecase == USECASE_AUDIO_PLAYBACK_LOW_LATENCY ||
               out->usecase == USECASE_AUDIO_PLAYBACK_DEEP_BUFFER ||
               out->usecase == USECASE_AUDIO_PLAYBACK_ULL) {
        pthread_mutex_lock(&out->latch_lock);
        /* Volume control for pcm playback */
        if (!out->standby)
        if (!out->standby && !out->a2dp_muted)
            ret = out_set_pcm_volume(stream, left, right);
        else
            out->apply_volume = true;

        out->volume_l = left;
        out->volume_r = right;
        pthread_mutex_unlock(&out->latch_lock);
        return ret;
    } else if (audio_extn_auto_hal_is_bus_device_usecase(out->usecase)) {
        ALOGV("%s: bus device set volume called", __func__);
        if (!out->standby)
        pthread_mutex_lock(&out->latch_lock);
        if (!out->standby && !out->a2dp_muted)
            ret = out_set_pcm_volume(stream, left, right);
        out->volume_l = left;
        out->volume_r = right;
        pthread_mutex_unlock(&out->latch_lock);
        return ret;
    }

@@ -5852,7 +5872,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
        (audio_extn_a2dp_source_is_suspended())) {
        if (!(compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER) ||
              compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER_SAFE))) {
            if (!(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
            if (!is_offload_usecase(out->usecase)) {
                ret = -EIO;
                goto exit;
            }
@@ -6018,10 +6038,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
    } else {
        if (out->pcm) {
            size_t bytes_to_write = bytes;
            pthread_mutex_lock(&out->latch_lock);
            if (out->muted)
                memset((void *)buffer, 0, bytes);
            pthread_mutex_unlock(&out->latch_lock);
            ALOGV("%s: frames=%zu, frame_size=%zu, bytes_to_write=%zu",
                     __func__, frames, frame_size, bytes_to_write);

@@ -6470,12 +6488,13 @@ static int out_flush(struct audio_stream_out* stream)
        lock_output_stream(out);
        pthread_mutex_lock(&out->latch_lock);
        if (out->offload_state == OFFLOAD_STATE_PAUSED) {
            pthread_mutex_unlock(&out->latch_lock);
            stop_compressed_output_l(out);
        } else {
            ALOGW("%s called in invalid state %d", __func__, out->offload_state);
            pthread_mutex_unlock(&out->latch_lock);
        }
        out->written = 0;
        pthread_mutex_unlock(&out->latch_lock);
        pthread_mutex_unlock(&out->lock);
        ALOGD("copl(%p):out of compress flush", out);
        return 0;
@@ -7773,7 +7792,7 @@ int adev_open_output_stream(struct audio_hw_device *dev,
    out->non_blocking = 0;
    out->convert_buffer = NULL;
    out->started = 0;
    out->a2dp_compress_mute = false;
    out->a2dp_muted = false;
    out->hal_output_suspend_supported = 0;
    out->dynamic_pm_qos_config_supported = 0;
    out->set_dual_mono = false;
@@ -8504,6 +8523,8 @@ int adev_open_output_stream(struct audio_hw_device *dev,
    out->kernel_buffer_size = out->config.period_size * out->config.period_count;

    out->standby = 1;
    out->volume_l = PLAYBACK_GAIN_MAX;
    out->volume_r = PLAYBACK_GAIN_MAX;
    /* out->muted = false; by calloc() */
    /* out->written = 0; by calloc() */

@@ -8644,7 +8665,7 @@ void adev_close_output_stream(struct audio_hw_device *dev __unused,
            free(out->compr_config.codec);
    }

    out->a2dp_compress_mute = false;
    out->a2dp_muted = false;

    if (is_interactive_usecase(out->usecase))
        free_interactive_usecase(adev, out->usecase);
@@ -8703,6 +8724,8 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
    /* notify adev and input/output streams on the snd card status */
    adev_snd_mon_cb((void *)adev, parms);

    ret = str_parms_get_str(parms, "SND_CARD_STATUS", value, sizeof(value));
    if (ret >= 0) {
        list_for_each(node, &adev->active_outputs_list) {
            streams_output_ctxt_t *out_ctxt = node_to_item(node,
                                                streams_output_ctxt_t,
@@ -8716,6 +8739,7 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
                                                list);
            in_snd_mon_cb((void *)in_ctxt->input, parms);
        }
    }

    pthread_mutex_lock(&adev->lock);
    ret = str_parms_get_str(parms, "BT_SCO", value, sizeof(value));
@@ -8897,17 +8921,12 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
                //force device switch to re configure encoder
                select_devices(adev, usecase->id);
                ALOGD("Unmuting the stream after select_devices");
                pthread_mutex_lock(&usecase->stream.out->latch_lock);
                usecase->stream.out->a2dp_compress_mute = false;
                out_set_compr_volume(&usecase->stream.out->stream,
                                     usecase->stream.out->volume_l,
                                     usecase->stream.out->volume_r);
                pthread_mutex_unlock(&usecase->stream.out->latch_lock);
                check_a2dp_restore_l(adev, usecase->stream.out, true);
                audio_extn_a2dp_set_handoff_mode(false);
                break;
            } else if (usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
            } else if (is_offload_usecase(usecase->stream.out->usecase)) {
                pthread_mutex_lock(&usecase->stream.out->latch_lock);
                if (usecase->stream.out->a2dp_compress_mute) {
                if (usecase->stream.out->a2dp_muted) {
                    pthread_mutex_unlock(&usecase->stream.out->latch_lock);
                    reassign_device_list(&usecase->stream.out->device_list,
                                         AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, "");
@@ -9523,6 +9542,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
        in->config.rate = config->sample_rate;
        in->af_period_multiplier = 1;
    } else if (in->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
               (!voice_extn_is_compress_voip_supported()) &&
               in->flags & AUDIO_INPUT_FLAG_VOIP_TX &&
               (config->sample_rate == 8000 ||
                config->sample_rate == 16000 ||
@@ -10357,8 +10377,8 @@ int check_a2dp_restore_l(struct audio_device *adev, struct stream_out *out, bool
    }
    list_init(&devices);

    ALOGD("%s: enter: usecase(%d: %s)", __func__,
          out->usecase, use_case_table[out->usecase]);
    ALOGD("%s: enter: usecase(%d: %s), a2dp muted %d", __func__,
          out->usecase, use_case_table[out->usecase], out->a2dp_muted);

    if (restore) {
        pthread_mutex_lock(&out->latch_lock);
@@ -10367,43 +10387,51 @@ int check_a2dp_restore_l(struct audio_device *adev, struct stream_out *out, bool
            ALOGD("%s: restoring A2dp and unmuting stream", __func__);
            if (uc_info->out_snd_device != SND_DEVICE_OUT_BT_A2DP)
                select_devices(adev, uc_info->id);
            if ((out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
                (uc_info->out_snd_device == SND_DEVICE_OUT_BT_A2DP)) {
                if (out->a2dp_compress_mute) {
                    out->a2dp_compress_mute = false;

            if (is_offload_usecase(out->usecase)) {
                if (uc_info->out_snd_device == SND_DEVICE_OUT_BT_A2DP)
                    out_set_compr_volume(&out->stream, out->volume_l, out->volume_r);
            } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
                out_set_voip_volume(&out->stream, out->volume_l, out->volume_r);
            } else {
                out_set_pcm_volume(&out->stream, out->volume_l, out->volume_r);
            }
            out->a2dp_muted = false;
        }
        }
        out->muted = false;
        pthread_mutex_unlock(&out->latch_lock);
    } else {
        pthread_mutex_lock(&out->latch_lock);
        if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
            // mute compress stream if suspended
            if (!out->a2dp_compress_mute && !out->standby) {
        // mute stream and switch to speaker if suspended
        if (!out->a2dp_muted && !out->standby) {
            ALOGD("%s: selecting speaker and muting stream", __func__);
            assign_devices(&devices, &out->device_list);
            reassign_device_list(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER, "");
            left_p = out->volume_l;
            right_p = out->volume_r;
            out->a2dp_muted = true;
            if (is_offload_usecase(out->usecase)) {
                if (out->offload_state == OFFLOAD_STATE_PLAYING)
                    compress_pause(out->compr);
                out_set_compr_volume(&out->stream, (float)0, (float)0);
                out->a2dp_compress_mute = true;
            } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
                out_set_voip_volume(&out->stream, (float)0, (float)0);
            } else {
                out_set_pcm_volume(&out->stream, (float)0, (float)0);
                /* wait for stale pcm drained before switching to speaker */
                uint32_t latency =
                    (out->config.period_count * out->config.period_size * 1000) /
                    (out->config.rate);
                usleep(latency * 1000);
            }
            select_devices(adev, out->usecase);
            if (is_offload_usecase(out->usecase)) {
                if (out->offload_state == OFFLOAD_STATE_PLAYING)
                    compress_resume(out->compr);
            }
            assign_devices(&out->device_list, &devices);
            out->volume_l = left_p;
            out->volume_r = right_p;
        }
        } else {
            // mute for non offloaded streams
            if (audio_extn_a2dp_source_is_suspended()) {
                out->muted = true;
            }
        }
        pthread_mutex_unlock(&out->latch_lock);
    }
    ALOGV("%s: exit", __func__);
+1 −1
Original line number Diff line number Diff line
@@ -442,7 +442,7 @@ struct stream_out {
    qahwi_stream_out_t qahwi_out;

    bool is_iec61937_info_available;
    bool a2dp_compress_mute;
    bool a2dp_muted;
    float volume_l;
    float volume_r;
    bool apply_volume;