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

Commit 99c752d8 authored by Ravi Kumar Alamanda's avatar Ravi Kumar Alamanda Committed by Eric Laurent
Browse files

Revert "Revert "audio: add support for routing to/from voice TX/RX paths""

This reverts commit 55a1293b.

Bug: 15520724.

Change-Id: I46c2402bedd513c148b2c309c6f18a7ef3aa4d2a
parent 3ad4e1b9
Loading
Loading
Loading
Loading
+178 −47
Original line number Diff line number Diff line
@@ -58,6 +58,9 @@
#define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96
#define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000

#define PROXY_OPEN_RETRY_COUNT           100
#define PROXY_OPEN_WAIT_TIME             20

static unsigned int configured_low_latency_capture_period_size =
        LOW_LATENCY_CAPTURE_PERIOD_SIZE;

@@ -105,6 +108,37 @@ struct pcm_config pcm_config_audio_capture = {
    .format = PCM_FORMAT_S16_LE,
};

#define AFE_PROXY_CHANNEL_COUNT 2
#define AFE_PROXY_SAMPLING_RATE 48000

#define AFE_PROXY_PLAYBACK_PERIOD_SIZE  768
#define AFE_PROXY_PLAYBACK_PERIOD_COUNT 4

struct pcm_config pcm_config_afe_proxy_playback = {
    .channels = AFE_PROXY_CHANNEL_COUNT,
    .rate = AFE_PROXY_SAMPLING_RATE,
    .period_size = AFE_PROXY_PLAYBACK_PERIOD_SIZE,
    .period_count = AFE_PROXY_PLAYBACK_PERIOD_COUNT,
    .format = PCM_FORMAT_S16_LE,
    .start_threshold = AFE_PROXY_PLAYBACK_PERIOD_SIZE,
    .stop_threshold = INT_MAX,
    .avail_min = AFE_PROXY_PLAYBACK_PERIOD_SIZE,
};

#define AFE_PROXY_RECORD_PERIOD_SIZE  768
#define AFE_PROXY_RECORD_PERIOD_COUNT 4

struct pcm_config pcm_config_afe_proxy_record = {
    .channels = AFE_PROXY_CHANNEL_COUNT,
    .rate = AFE_PROXY_SAMPLING_RATE,
    .period_size = AFE_PROXY_RECORD_PERIOD_SIZE,
    .period_count = AFE_PROXY_RECORD_PERIOD_COUNT,
    .format = PCM_FORMAT_S16_LE,
    .start_threshold = AFE_PROXY_RECORD_PERIOD_SIZE,
    .stop_threshold = INT_MAX,
    .avail_min = AFE_PROXY_RECORD_PERIOD_SIZE,
};

const char * const use_case_table[AUDIO_USECASE_MAX] = {
    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "deep-buffer-playback",
    [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback",
@@ -122,6 +156,9 @@ const char * const use_case_table[AUDIO_USECASE_MAX] = {
    [USECASE_VOLTE_CALL] = "volte-call",
    [USECASE_QCHAT_CALL] = "qchat-call",
    [USECASE_VOWLAN_CALL] = "vowlan-call",

    [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = "afe-proxy-playback",
    [USECASE_AUDIO_RECORD_AFE_PROXY] = "afe-proxy-record",
};


@@ -536,14 +573,14 @@ int select_devices(struct audio_device *adev,
            usecase->devices = usecase->stream.in->device;
            out_snd_device = SND_DEVICE_NONE;
            if (in_snd_device == SND_DEVICE_NONE) {
                audio_devices_t out_device = AUDIO_DEVICE_NONE;
                if (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
                        adev->primary_output && !adev->primary_output->standby) {
                    in_snd_device = platform_get_input_snd_device(adev->platform,
                                        adev->primary_output->devices);
                } else {
                    in_snd_device = platform_get_input_snd_device(adev->platform,
                                                                  AUDIO_DEVICE_NONE);
                    out_device = adev->primary_output->devices;
                } else if (usecase->id == USECASE_AUDIO_RECORD_AFE_PROXY) {
                    out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX;
                }
                in_snd_device = platform_get_input_snd_device(adev->platform, out_device);
            }
        }
    }
@@ -680,15 +717,34 @@ int start_input_stream(struct stream_in *in)

    ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
          __func__, adev->snd_card, in->pcm_device_id, in->config.channels);

    unsigned int flags = PCM_IN;
    unsigned int pcm_open_retry_count = 0;

    if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) {
        flags |= PCM_MMAP | PCM_NOIRQ;
        pcm_open_retry_count = PROXY_OPEN_RETRY_COUNT;
    }

    while (1) {
        in->pcm = pcm_open(adev->snd_card, in->pcm_device_id,
                           PCM_IN, &in->config);
    if (in->pcm && !pcm_is_ready(in->pcm)) {
                           flags, &in->config);
        if (in->pcm == NULL || !pcm_is_ready(in->pcm)) {
            ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
            if (in->pcm != NULL) {
                pcm_close(in->pcm);
                in->pcm = NULL;
            }
            if (pcm_open_retry_count-- == 0) {
                ret = -EIO;
                goto error_open;
            }
            usleep(PROXY_OPEN_WAIT_TIME * 1000);
            continue;
        }
        break;
    }

    ALOGV("%s: exit", __func__);
    return ret;

@@ -992,15 +1048,32 @@ int start_output_stream(struct stream_out *out)
    ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
          __func__, adev->snd_card, out->pcm_device_id, out->config.format);
    if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
        unsigned int flags = PCM_OUT;
        unsigned int pcm_open_retry_count = 0;
        if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) {
            flags |= PCM_MMAP | PCM_NOIRQ;
            pcm_open_retry_count = PROXY_OPEN_RETRY_COUNT;
        } else
            flags |= PCM_MONOTONIC;

        while (1) {
            out->pcm = pcm_open(adev->snd_card, out->pcm_device_id,
                               PCM_OUT | PCM_MONOTONIC, &out->config);
        if (out->pcm && !pcm_is_ready(out->pcm)) {
                               flags, &out->config);
            if (out->pcm == NULL || !pcm_is_ready(out->pcm)) {
                ALOGE("%s: %s", __func__, pcm_get_error(out->pcm));
                if (out->pcm != NULL) {
                    pcm_close(out->pcm);
                    out->pcm = NULL;
                }
                if (pcm_open_retry_count-- == 0) {
                    ret = -EIO;
                    goto error_open;
                }
                usleep(PROXY_OPEN_WAIT_TIME * 1000);
                continue;
            }
            break;
        }
    } else {
        out->pcm = NULL;
        out->compr = compress_open(adev->snd_card, out->pcm_device_id,
@@ -1101,7 +1174,6 @@ static size_t out_get_buffer_size(const struct audio_stream *stream)
    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
        return out->compr_config.fragment_size;
    }

    return out->config.period_size *
                audio_stream_out_frame_size((const struct audio_stream_out *)stream);
}
@@ -1196,6 +1268,10 @@ static int parse_compress_metadata(struct stream_out *out, struct str_parms *par
    return 0;
}

static bool output_drives_call(struct audio_device *adev, struct stream_out *out)
{
    return out == adev->primary_output || out == adev->voice_tx_output;
}

static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
{
@@ -1255,20 +1331,24 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
                select_devices(adev, out->usecase);

            if ((adev->mode == AUDIO_MODE_IN_CALL) &&
                    !voice_is_in_call(adev) &&
                    (out == adev->primary_output)) {
                ret = voice_start_call(adev);
            } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
                            voice_is_in_call(adev) &&
                            (out == adev->primary_output)) {
                    output_drives_call(adev, out)) {

                if (adev->current_call_output != out) {
                    voice_stop_call(adev);
                }
                if (!voice_is_in_call(adev)) {
                    ret = voice_start_call(adev, out);
                    adev->current_call_output = out;
                } else
                    voice_update_devices_for_all_voice_usecases(adev);
            }
        }

        if ((adev->mode == AUDIO_MODE_NORMAL) &&
                voice_is_in_call(adev) &&
                (out == adev->primary_output)) {
                output_drives_call(adev, out)) {
            ret = voice_stop_call(adev);
            adev->current_call_output = NULL;
        }

        pthread_mutex_unlock(&adev->lock);
@@ -1416,6 +1496,10 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
            if (out->muted)
                memset((void *)buffer, 0, bytes);
            ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
            if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) {
                ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes);
            }
            else
                ret = pcm_write(out->pcm, (void *)buffer, bytes);
            if (ret == 0)
                out->written += bytes / (out->config.channels * sizeof(short));
@@ -1686,7 +1770,7 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)

    if (ret >= 0) {
        val = atoi(value);
        if ((in->device != val) && (val != 0)) {
        if (((int)in->device != val) && (val != 0)) {
            in->device = val;
            /* If recording is in progress, change the tx device to new device */
            if (!in->standby)
@@ -1732,6 +1816,9 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
    }

    if (in->pcm) {
        if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) {
            ret = pcm_mmap_read(in->pcm, buffer, bytes);
        } else
            ret = pcm_read(in->pcm, buffer, bytes);
    }

@@ -1907,6 +1994,28 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
        ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
                __func__, config->offload_info.version,
                config->offload_info.bit_rate);
    } else  if (out->devices == AUDIO_DEVICE_OUT_TELEPHONY_TX) {
        if (config->sample_rate == 0)
            config->sample_rate = AFE_PROXY_SAMPLING_RATE;
        if (config->sample_rate != 48000 && config->sample_rate != 16000 &&
                config->sample_rate != 8000) {
            config->sample_rate = AFE_PROXY_SAMPLING_RATE;
            ret = -EINVAL;
            goto error_open;
        }
        out->sample_rate = config->sample_rate;
        out->config.rate = config->sample_rate;
        if (config->format == AUDIO_FORMAT_DEFAULT)
            config->format = AUDIO_FORMAT_PCM_16_BIT;
        if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
            config->format = AUDIO_FORMAT_PCM_16_BIT;
            ret = -EINVAL;
            goto error_open;
        }
        out->format = config->format;
        out->usecase = USECASE_AUDIO_PLAYBACK_AFE_PROXY;
        out->config = pcm_config_afe_proxy_playback;
        adev->voice_tx_output = out;
    } else {
        if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
            out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
@@ -2215,6 +2324,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
    struct stream_in *in;
    int ret = 0, buffer_size, frame_size;
    int channel_count = audio_channel_count_from_in_mask(config->channel_mask);
    bool is_low_latency = false;

    ALOGV("%s: enter", __func__);
    *stream_in = NULL;
@@ -2248,8 +2358,27 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
    in->channel_mask = config->channel_mask;

    /* Update config params with the requested sample rate and channels */
    if (in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
        if (config->sample_rate == 0)
            config->sample_rate = AFE_PROXY_SAMPLING_RATE;
        if (config->sample_rate != 48000 && config->sample_rate != 16000 &&
                config->sample_rate != 8000) {
            config->sample_rate = AFE_PROXY_SAMPLING_RATE;
            ret = -EINVAL;
            goto err_open;
        }
        if (config->format == AUDIO_FORMAT_DEFAULT)
            config->format = AUDIO_FORMAT_PCM_16_BIT;
        if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
            config->format = AUDIO_FORMAT_PCM_16_BIT;
            ret = -EINVAL;
            goto err_open;
        }

        in->usecase = USECASE_AUDIO_RECORD_AFE_PROXY;
        in->config = pcm_config_afe_proxy_record;
    } else {
        in->usecase = USECASE_AUDIO_RECORD;
    bool is_low_latency = false;
        if (config->sample_rate == LOW_LATENCY_CAPTURE_SAMPLE_RATE &&
                (flags & AUDIO_INPUT_FLAG_FAST) != 0) {
            is_low_latency = true;
@@ -2258,8 +2387,6 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
#endif
        }
        in->config = pcm_config_audio_capture;
    in->config.channels = channel_count;
    in->config.rate = config->sample_rate;

        frame_size = audio_stream_in_frame_size(&in->stream);
        buffer_size = get_input_buffer_size(config->sample_rate,
@@ -2267,6 +2394,10 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
                                            channel_count,
                                            is_low_latency);
        in->config.period_size = buffer_size / frame_size;
    }
    in->config.channels = channel_count;
    in->config.rate = config->sample_rate;


    *stream_in = &in->stream;
    ALOGV("%s: exit", __func__);
+7 −1
Original line number Diff line number Diff line
@@ -76,6 +76,10 @@ enum {
    USECASE_INCALL_REC_UPLINK,
    USECASE_INCALL_REC_DOWNLINK,
    USECASE_INCALL_REC_UPLINK_AND_DOWNLINK,

    USECASE_AUDIO_PLAYBACK_AFE_PROXY,
    USECASE_AUDIO_RECORD_AFE_PROXY,

    AUDIO_USECASE_MAX
};

@@ -157,7 +161,7 @@ struct stream_in {
    int standby;
    int source;
    int pcm_device_id;
    int device;
    audio_devices_t device;
    audio_channel_mask_t channel_mask;
    audio_usecase_t usecase;
    bool enable_aec;
@@ -195,6 +199,8 @@ struct audio_device {
    audio_mode_t mode;
    struct stream_in *active_input;
    struct stream_out *primary_output;
    struct stream_out *voice_tx_output;
    struct stream_out *current_call_output;
    bool bluetooth_nrec;
    bool screen_off;
    int *snd_dev_ref_cnt;
+4 −0
Original line number Diff line number Diff line
@@ -120,4 +120,8 @@ enum {
#define LOW_LATENCY_CAPTURE_PERIOD_SIZE 240
#define LOW_LATENCY_CAPTURE_USE_CASE 0

#define AFE_PROXY_PLAYBACK_PCM_DEVICE 7
#define AFE_PROXY_RECORD_PCM_DEVICE 8


#endif // QCOM_AUDIO_PLATFORM_H
+19 −2
Original line number Diff line number Diff line
@@ -115,6 +115,12 @@ static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
    [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
                                                AUDIO_RECORD_PCM_DEVICE},
    [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},

    [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
                                          AFE_PROXY_RECORD_PCM_DEVICE},
    [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
                                        AFE_PROXY_RECORD_PCM_DEVICE},

};

/* Array to store sound devices */
@@ -140,6 +146,7 @@ static const char * const device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
    [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
    [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
    [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",

    /* Capture sound devices */
    [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
@@ -183,6 +190,8 @@ static const char * const device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
    [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
    [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",

    [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
};

/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
@@ -207,6 +216,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
    [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
    [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
    [SND_DEVICE_OUT_VOICE_TX] = 45,

    [SND_DEVICE_IN_HANDSET_MIC] = 4,
    [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
@@ -249,6 +259,8 @@ static int acdb_device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 113,
    [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 35,
    [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 43,

    [SND_DEVICE_IN_VOICE_RX] = 44,
};

struct name_to_index {
@@ -595,6 +607,8 @@ static void set_platform_defaults(struct platform_data * my_data)
    backend_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
    backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
    backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
    backend_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
    backend_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");

    if (my_data->ext_speaker) {
        backend_table[SND_DEVICE_OUT_SPEAKER] = strdup("speaker");
@@ -1181,7 +1195,9 @@ snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devi
                snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
            else
                snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
        }
        } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
            snd_device = SND_DEVICE_OUT_VOICE_TX;

        if (snd_device != SND_DEVICE_NONE) {
            goto exit;
        }
@@ -1313,7 +1329,8 @@ snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_d
                snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
                set_echo_reference(adev, true);
            }
        }
        } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
            snd_device = SND_DEVICE_IN_VOICE_RX;
    } else if (source == AUDIO_SOURCE_CAMCORDER) {
        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
            in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+6 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ enum {
    SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
    SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
    SND_DEVICE_OUT_VOICE_HAC_HANDSET,
    SND_DEVICE_OUT_VOICE_TX,
    SND_DEVICE_OUT_END,

    /*
@@ -105,6 +106,8 @@ enum {
    SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
    SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,

    SND_DEVICE_IN_VOICE_RX,

    SND_DEVICE_IN_END,

    SND_DEVICE_MAX = SND_DEVICE_IN_END,
@@ -179,6 +182,9 @@ enum {
#define VOWLAN_CALL_PCM_DEVICE 36
#endif

#define AFE_PROXY_PLAYBACK_PCM_DEVICE 7
#define AFE_PROXY_RECORD_PCM_DEVICE 8

#define HFP_PCM_RX 5
#ifdef PLATFORM_MSM8x26
#define HFP_SCO_RX 28
Loading