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

Commit 1842e0f2 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5316819 from 6f2d5cd3 to qt-release

Change-Id: I71c5c0573bd87063de01c3e63c57e1d2ffb4d8d2
parents a01ef2fb 6f2d5cd3
Loading
Loading
Loading
Loading
+270 −39
Original line number Original line Diff line number Diff line
@@ -131,6 +131,26 @@ struct pcm_config pcm_config_low_latency = {
    .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
    .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
};
};


struct pcm_config pcm_config_haptics_audio = {
    .channels = 1,
    .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
    .period_size = LOW_LATENCY_OUTPUT_PERIOD_SIZE,
    .period_count = LOW_LATENCY_OUTPUT_PERIOD_COUNT,
    .format = PCM_FORMAT_S16_LE,
    .start_threshold = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
    .stop_threshold = INT_MAX,
    .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
};

struct pcm_config pcm_config_haptics = {
    .channels = 1,
    .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
    .period_count = 2,
    .format = PCM_FORMAT_S16_LE,
    .stop_threshold = INT_MAX,
    .avail_min = 0,
};

static int af_period_multiplier = 4;
static int af_period_multiplier = 4;
struct pcm_config pcm_config_rt = {
struct pcm_config pcm_config_rt = {
    .channels = DEFAULT_CHANNEL_COUNT,
    .channels = DEFAULT_CHANNEL_COUNT,
@@ -256,6 +276,7 @@ struct pcm_config pcm_config_afe_proxy_record = {
const char * const use_case_table[AUDIO_USECASE_MAX] = {
const char * const use_case_table[AUDIO_USECASE_MAX] = {
    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "deep-buffer-playback",
    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "deep-buffer-playback",
    [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback",
    [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback",
    [USECASE_AUDIO_PLAYBACK_WITH_HAPTICS] = "audio-with-haptics-playback",
    [USECASE_AUDIO_PLAYBACK_HIFI] = "hifi-playback",
    [USECASE_AUDIO_PLAYBACK_HIFI] = "hifi-playback",
    [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
    [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
    [USECASE_AUDIO_PLAYBACK_TTS] = "audio-tts-playback",
    [USECASE_AUDIO_PLAYBACK_TTS] = "audio-tts-playback",
@@ -1510,6 +1531,7 @@ int select_devices(struct audio_device *adev,
                                               get_voice_usecase_id_from_list(adev));
                                               get_voice_usecase_id_from_list(adev));
            if ((vc_usecase != NULL) &&
            if ((vc_usecase != NULL) &&
                ((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
                ((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
                 (vc_usecase->devices == AUDIO_DEVICE_OUT_HEARING_AID) ||
                 (usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL))) {
                 (usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL))) {
                in_snd_device = vc_usecase->in_snd_device;
                in_snd_device = vc_usecase->in_snd_device;
                out_snd_device = vc_usecase->out_snd_device;
                out_snd_device = vc_usecase->out_snd_device;
@@ -1556,8 +1578,13 @@ int select_devices(struct audio_device *adev,
                        out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX;
                        out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX;
                    } else if (voip_usecase) {
                    } else if (voip_usecase) {
                        out_device = voip_usecase->stream.out->devices;
                        out_device = voip_usecase->stream.out->devices;
                    } else if (adev->primary_output) {
                    } else if (adev->primary_output &&
                                  !adev->primary_output->standby) {
                        out_device = adev->primary_output->devices;
                        out_device = adev->primary_output->devices;
                    } else {
                        /* forcing speaker o/p device to get matching i/p pair
                           in case o/p is not routed from same primary HAL */
                        out_device = AUDIO_DEVICE_OUT_SPEAKER;
                    }
                    }
                }
                }
                in_snd_device = platform_get_input_snd_device(adev->platform,
                in_snd_device = platform_get_input_snd_device(adev->platform,
@@ -2213,14 +2240,19 @@ static int stop_output_stream(struct stream_out *out)
        }
        }
        ret = 0;
        ret = 0;
    }
    }

    /* 1) media + voip output routing to handset must route media back to
          speaker when voip stops.
       2) trigger voip input to reroute when voip output changes to
          hearing aid. */
    if (has_voip_usecase ||
    if (has_voip_usecase ||
            out->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
            out->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
        struct listnode *node;
        struct listnode *node;
        struct audio_usecase *usecase;
        struct audio_usecase *usecase;
        list_for_each(node, &adev->usecase_list) {
        list_for_each(node, &adev->usecase_list) {
            usecase = node_to_item(node, struct audio_usecase, list);
            usecase = node_to_item(node, struct audio_usecase, list);
            if (usecase->type == PCM_CAPTURE || usecase == uc_info)
            if ((usecase->type == PCM_CAPTURE &&
                     usecase->id != USECASE_AUDIO_RECORD_VOIP)
                || usecase == uc_info)
                continue;
                continue;


            ALOGD("%s: select_devices at usecase(%d: %s) after removing the usecase(%d: %s)",
            ALOGD("%s: select_devices at usecase(%d: %s) after removing the usecase(%d: %s)",
@@ -2235,6 +2267,41 @@ static int stop_output_stream(struct stream_out *out)
    return ret;
    return ret;
}
}


struct pcm* pcm_open_prepare_helper(unsigned int snd_card, unsigned int pcm_device_id,
                                   unsigned int flags, unsigned int pcm_open_retry_count,
                                   struct pcm_config *config)
{
    struct pcm* pcm = NULL;

    while (1) {
        pcm = pcm_open(snd_card, pcm_device_id, flags, config);
        if (pcm == NULL || !pcm_is_ready(pcm)) {
            ALOGE("%s: %s", __func__, pcm_get_error(pcm));
            if (pcm != NULL) {
                pcm_close(pcm);
                pcm = NULL;
            }
            if (pcm_open_retry_count-- == 0)
                return NULL;

            usleep(PROXY_OPEN_WAIT_TIME * 1000);
            continue;
        }
        break;
    }

    if (pcm_is_ready(pcm)) {
        int ret = pcm_prepare(pcm);
        if (ret < 0) {
            ALOGE("%s: pcm_prepare returned %d", __func__, ret);
            pcm_close(pcm);
            pcm = NULL;
        }
    }

    return pcm;
}

int start_output_stream(struct stream_out *out)
int start_output_stream(struct stream_out *out)
{
{
    int ret = 0;
    int ret = 0;
@@ -2242,8 +2309,10 @@ int start_output_stream(struct stream_out *out)
    struct audio_device *adev = out->dev;
    struct audio_device *adev = out->dev;
    bool a2dp_combo = false;
    bool a2dp_combo = false;


    ALOGV("%s: enter: usecase(%d: %s) devices(%#x)",
    ALOGV("%s: enter: usecase(%d: %s) %s devices(%#x)",
          __func__, out->usecase, use_case_table[out->usecase], out->devices);
          __func__, out->usecase, use_case_table[out->usecase],
          out->usecase == USECASE_AUDIO_PLAYBACK_WITH_HAPTICS ? "(with haptics)" : "",
          out->devices);


    if (out->card_status == CARD_STATUS_OFFLINE ||
    if (out->card_status == CARD_STATUS_OFFLINE ||
        adev->card_status == CARD_STATUS_OFFLINE) {
        adev->card_status == CARD_STATUS_OFFLINE) {
@@ -2363,34 +2432,27 @@ int start_output_stream(struct stream_out *out)
            flags |= PCM_MMAP | PCM_NOIRQ;
            flags |= PCM_MMAP | PCM_NOIRQ;
        }
        }


        while (1) {
        out->pcm = pcm_open_prepare_helper(adev->snd_card, out->pcm_device_id,
            out->pcm = pcm_open(adev->snd_card, out->pcm_device_id,
                                       flags, pcm_open_retry_count,
                               flags, &out->config);
                                       &(out->config));
            if (out->pcm == NULL || !pcm_is_ready(out->pcm)) {
        if (out->pcm == NULL) {
                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;
           ret = -EIO;
           goto error_open;
           goto error_open;
        }
        }
                usleep(PROXY_OPEN_WAIT_TIME * 1000);

                continue;
        if (out->usecase == USECASE_AUDIO_PLAYBACK_WITH_HAPTICS) {
            }
            if (adev->haptic_pcm != NULL) {
            break;
                pcm_close(adev->haptic_pcm);
        }
                adev->haptic_pcm = NULL;
        ALOGV("%s: pcm_prepare", __func__);
        if (pcm_is_ready(out->pcm)) {
            ret = pcm_prepare(out->pcm);
            if (ret < 0) {
                ALOGE("%s: pcm_prepare returned %d", __func__, ret);
                pcm_close(out->pcm);
                out->pcm = NULL;
                goto error_open;
            }
            }
            adev->haptic_pcm = pcm_open_prepare_helper(adev->snd_card,
                                   adev->haptic_pcm_device_id,
                                   flags, pcm_open_retry_count,
                                   &(adev->haptics_config));
            // failure to open haptics pcm shouldnt stop audio,
            // so do not close audio pcm in case of error
        }
        }

        if (out->realtime) {
        if (out->realtime) {
            ret = pcm_start(out->pcm);
            ret = pcm_start(out->pcm);
            if (ret < 0) {
            if (ret < 0) {
@@ -2401,6 +2463,7 @@ int start_output_stream(struct stream_out *out)
            }
            }
        }
        }
    }
    }

    register_out_stream(out);
    register_out_stream(out);
    audio_streaming_hint_end();
    audio_streaming_hint_end();
    audio_extn_perf_lock_release();
    audio_extn_perf_lock_release();
@@ -2414,13 +2477,17 @@ int start_output_stream(struct stream_out *out)
    // consider a scenario where on pause lower layers are tear down.
    // consider a scenario where on pause lower layers are tear down.
    // so on resume, swap mixer control need to be sent only when
    // so on resume, swap mixer control need to be sent only when
    // backend is active, hence rather than sending from enable device
    // backend is active, hence rather than sending from enable device
    // sending it from start of streamtream
    // sending it from start of stream


    platform_set_swap_channels(adev, true);
    platform_set_swap_channels(adev, true);


    ALOGV("%s: exit", __func__);
    ALOGV("%s: exit", __func__);
    return 0;
    return 0;
error_open:
error_open:
    if (adev->haptic_pcm) {
        pcm_close(adev->haptic_pcm);
        adev->haptic_pcm = NULL;
    }
    audio_streaming_hint_end();
    audio_streaming_hint_end();
    audio_extn_perf_lock_release();
    audio_extn_perf_lock_release();
    stop_output_stream(out);
    stop_output_stream(out);
@@ -2594,6 +2661,19 @@ static int out_standby_l(struct audio_stream *stream)
            if (out->pcm) {
            if (out->pcm) {
                pcm_close(out->pcm);
                pcm_close(out->pcm);
                out->pcm = NULL;
                out->pcm = NULL;

                if (out->usecase == USECASE_AUDIO_PLAYBACK_WITH_HAPTICS) {
                    if (adev->haptic_pcm) {
                        pcm_close(adev->haptic_pcm);
                        adev->haptic_pcm = NULL;
                    }

                    if (adev->haptic_buffer != NULL) {
                        free(adev->haptic_buffer);
                        adev->haptic_buffer = NULL;
                        adev->haptic_buffer_size = 0;
                    }
                }
            }
            }
            if (out->usecase == USECASE_AUDIO_PLAYBACK_MMAP) {
            if (out->usecase == USECASE_AUDIO_PLAYBACK_MMAP) {
                do_stop = out->playback_started;
                do_stop = out->playback_started;
@@ -3294,11 +3374,77 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
            request_out_focus(out, ns);
            request_out_focus(out, ns);


            bool use_mmap = is_mmap_usecase(out->usecase) || out->realtime;
            bool use_mmap = is_mmap_usecase(out->usecase) || out->realtime;
            if (use_mmap)
            if (use_mmap) {
                ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes_to_write);
                ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes_to_write);
            else
            } else {
                ret = pcm_write(out->pcm, (void *)buffer, bytes_to_write);
                if (out->usecase == USECASE_AUDIO_PLAYBACK_WITH_HAPTICS) {
                    size_t channel_count = audio_channel_count_from_out_mask(out->channel_mask);
                    size_t bytes_per_sample = audio_bytes_per_sample(out->format);
                    size_t frame_size = channel_count * bytes_per_sample;
                    size_t frame_count = bytes_to_write / frame_size;

                    bool force_haptic_path =
                         property_get_bool("vendor.audio.test_haptic", false);

                    // extract Haptics data from Audio buffer
                    bool   alloc_haptic_buffer = false;
                    int    haptic_channel_count = adev->haptics_config.channels;
                    size_t haptic_frame_size = bytes_per_sample * haptic_channel_count;
                    size_t audio_frame_size = frame_size - haptic_frame_size;
                    size_t total_haptic_buffer_size = frame_count * haptic_frame_size;

                    if (adev->haptic_buffer == NULL) {
                        alloc_haptic_buffer = true;
                    } else if (adev->haptic_buffer_size < total_haptic_buffer_size) {
                        free(adev->haptic_buffer);
                        adev->haptic_buffer_size = 0;
                        alloc_haptic_buffer = true;
                    }

                    if (alloc_haptic_buffer) {
                        adev->haptic_buffer = (uint8_t *)calloc(1, total_haptic_buffer_size);
                        adev->haptic_buffer_size = total_haptic_buffer_size;
                    }

                    size_t src_index = 0, aud_index = 0, hap_index = 0;
                    uint8_t *audio_buffer = (uint8_t *)buffer;
                    uint8_t *haptic_buffer  = adev->haptic_buffer;

                    // This is required for testing only. This works for stereo data only.
                    // One channel is fed to audio stream and other to haptic stream for testing.
                    if (force_haptic_path) {
                       audio_frame_size = haptic_frame_size = bytes_per_sample;
                    }

                    for (size_t i = 0; i < frame_count; i++) {
                        for (size_t j = 0; j < audio_frame_size; j++)
                            audio_buffer[aud_index++] = audio_buffer[src_index++];

                        for (size_t j = 0; j < haptic_frame_size; j++)
                            haptic_buffer[hap_index++] = audio_buffer[src_index++];
                        }

                        // This is required for testing only.
                        // Discard haptic channel data.
                        if (force_haptic_path) {
                            src_index += haptic_frame_size;
                    }

                    // write to audio pipeline
                    ret = pcm_write(out->pcm,
                                    (void *)audio_buffer,
                                    frame_count * audio_frame_size);

                    // write to haptics pipeline
                    if (adev->haptic_pcm)
                        ret = pcm_write(adev->haptic_pcm,
                                        (void *)adev->haptic_buffer,
                                        frame_count * haptic_frame_size);


                } else {
                    ret = pcm_write(out->pcm, (void *)buffer, bytes_to_write);
                }
            }
            release_out_focus(out, ns);
            release_out_focus(out, ns);
        } else {
        } else {
            LOG_ALWAYS_FATAL("out->pcm is NULL after starting output stream");
            LOG_ALWAYS_FATAL("out->pcm is NULL after starting output stream");
@@ -4377,6 +4523,52 @@ static int in_set_microphone_field_dimension(const struct audio_stream_in *strea
    return -ENOSYS;
    return -ENOSYS;
}
}


static void in_update_sink_metadata(struct audio_stream_in *stream,
                                    const struct sink_metadata *sink_metadata) {

    if (stream == NULL
            || sink_metadata == NULL
            || sink_metadata->tracks == NULL) {
        return;
    }

    int error = 0;
    struct stream_in *in = (struct stream_in *)stream;
    struct audio_device *adev = in->dev;
    audio_devices_t device = AUDIO_DEVICE_NONE;

    if (sink_metadata->track_count != 0)
        device = sink_metadata->tracks->dest_device;

    lock_input_stream(in);
    pthread_mutex_lock(&adev->lock);
    ALOGV("%s: in->usecase: %d, device: %x", __func__, in->usecase, device);

    if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY
            && device != AUDIO_DEVICE_NONE
            && adev->voice_tx_output != NULL) {
        /* Use the rx device from afe-proxy record to route voice call because
           there is no routing if tx device is on primary hal and rx device
           is on other hal during voice call. */
        adev->voice_tx_output->devices = device;

        if (!voice_is_call_state_active(adev)) {
            if (adev->mode == AUDIO_MODE_IN_CALL) {
                adev->current_call_output = adev->voice_tx_output;
                error = voice_start_call(adev);
                if (error != 0)
                    ALOGE("%s: start voice call failed %d", __func__, error);
            }
        } else {
            adev->current_call_output = adev->voice_tx_output;
            voice_update_devices_for_all_voice_usecases(adev);
        }
    }

    pthread_mutex_unlock(&adev->lock);
    pthread_mutex_unlock(&in->lock);
}

static int adev_open_output_stream(struct audio_hw_device *dev,
static int adev_open_output_stream(struct audio_hw_device *dev,
                                   audio_io_handle_t handle,
                                   audio_io_handle_t handle,
                                   audio_devices_t devices,
                                   audio_devices_t devices,
@@ -4391,6 +4583,8 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
    bool is_hdmi = devices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
    bool is_hdmi = devices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
    bool is_usb_dev = audio_is_usb_out_device(devices) &&
    bool is_usb_dev = audio_is_usb_out_device(devices) &&
                      (devices != AUDIO_DEVICE_OUT_USB_ACCESSORY);
                      (devices != AUDIO_DEVICE_OUT_USB_ACCESSORY);
    bool force_haptic_path =
            property_get_bool("vendor.audio.test_haptic", false);


    if (is_usb_dev && !is_usb_ready(adev, true /* is_playback */)) {
    if (is_usb_dev && !is_usb_ready(adev, true /* is_playback */)) {
        return -ENOSYS;
        return -ENOSYS;
@@ -4398,6 +4592,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,


    ALOGV("%s: enter: format(%#x) sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
    ALOGV("%s: enter: format(%#x) sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
          __func__, config->format, config->sample_rate, config->channel_mask, devices, flags);
          __func__, config->format, config->sample_rate, config->channel_mask, devices, flags);

    *stream_out = NULL;
    *stream_out = NULL;
    out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
    out = (struct stream_out *)calloc(1, sizeof(struct stream_out));


@@ -4727,21 +4922,39 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
            out->stream.stop = out_stop;
            out->stream.stop = out_stop;
            out->stream.create_mmap_buffer = out_create_mmap_buffer;
            out->stream.create_mmap_buffer = out_create_mmap_buffer;
            out->stream.get_mmap_position = out_get_mmap_position;
            out->stream.get_mmap_position = out_get_mmap_position;
        } else {
            if (config->channel_mask & AUDIO_CHANNEL_HAPTIC_ALL) {
                out->usecase = USECASE_AUDIO_PLAYBACK_WITH_HAPTICS;
                adev->haptic_pcm_device_id = platform_get_haptics_pcm_device_id();
                if (adev->haptic_pcm_device_id < 0) {
                    ALOGE("%s: Invalid Haptics pcm device id(%d) for the usecase(%d)",
                          __func__, adev->haptic_pcm_device_id, out->usecase);
                    ret = -ENOSYS;
                    goto error_open;
                }
                out->config = pcm_config_haptics_audio;
                if (force_haptic_path)
                    adev->haptics_config = pcm_config_haptics_audio;
                else
                    adev->haptics_config = pcm_config_haptics;
            } else {
            } else {
                out->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY;
                out->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY;
                out->config = pcm_config_low_latency;
                out->config = pcm_config_low_latency;
            }
            }
        }


        if (config->sample_rate == 0) {
        if (config->sample_rate == 0) {
            out->sample_rate = out->config.rate;
            out->sample_rate = out->config.rate;
        } else {
        } else {
            out->sample_rate = config->sample_rate;
            out->sample_rate = config->sample_rate;
        }
        }

        if (config->channel_mask == AUDIO_CHANNEL_NONE) {
        if (config->channel_mask == AUDIO_CHANNEL_NONE) {
            out->channel_mask = audio_channel_out_mask_from_count(out->config.channels);
            out->channel_mask = audio_channel_out_mask_from_count(out->config.channels);
        } else {
        } else {
            out->channel_mask = config->channel_mask;
            out->channel_mask = config->channel_mask;
        }
        }

        if (config->format == AUDIO_FORMAT_DEFAULT)
        if (config->format == AUDIO_FORMAT_DEFAULT)
            out->format = audio_format_from_pcm_format(out->config.format);
            out->format = audio_format_from_pcm_format(out->config.format);
        else if (!audio_is_linear_pcm(config->format)) {
        else if (!audio_is_linear_pcm(config->format)) {
@@ -4753,8 +4966,25 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
        }
        }


        out->config.rate = out->sample_rate;
        out->config.rate = out->sample_rate;

        if (config->channel_mask & AUDIO_CHANNEL_HAPTIC_ALL) {
             out->config.channels =
                audio_channel_count_from_out_mask(out->channel_mask &
                                                  ~AUDIO_CHANNEL_HAPTIC_ALL);

             if (force_haptic_path) {
                 out->config.channels = 1;
                 adev->haptics_config.channels = 1;
             } else {
                 adev->haptics_config.channels =
                     audio_channel_count_from_out_mask(out->channel_mask &
                                                      AUDIO_CHANNEL_HAPTIC_ALL);
             }
        } else {
             out->config.channels =
             out->config.channels =
                    audio_channel_count_from_out_mask(out->channel_mask);
                    audio_channel_count_from_out_mask(out->channel_mask);
        }

        if (out->format != audio_format_from_pcm_format(out->config.format)) {
        if (out->format != audio_format_from_pcm_format(out->config.format)) {
            out->config.format = pcm_format_from_audio_format(out->format);
            out->config.format = pcm_format_from_audio_format(out->format);
        }
        }
@@ -5306,6 +5536,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
    in->stream.get_active_microphones = in_get_active_microphones;
    in->stream.get_active_microphones = in_get_active_microphones;
    in->stream.set_microphone_direction = in_set_microphone_direction;
    in->stream.set_microphone_direction = in_set_microphone_direction;
    in->stream.set_microphone_field_dimension = in_set_microphone_field_dimension;
    in->stream.set_microphone_field_dimension = in_set_microphone_field_dimension;
    in->stream.update_sink_metadata = in_update_sink_metadata;


    in->device = devices;
    in->device = devices;
    in->source = source;
    in->source = source;
+8 −0
Original line number Original line Diff line number Diff line
@@ -82,6 +82,7 @@ enum {
    USECASE_AUDIO_PLAYBACK_TTS,
    USECASE_AUDIO_PLAYBACK_TTS,
    USECASE_AUDIO_PLAYBACK_ULL,
    USECASE_AUDIO_PLAYBACK_ULL,
    USECASE_AUDIO_PLAYBACK_MMAP,
    USECASE_AUDIO_PLAYBACK_MMAP,
    USECASE_AUDIO_PLAYBACK_WITH_HAPTICS,


    /* HFP Use case*/
    /* HFP Use case*/
    USECASE_AUDIO_HFP_SCO,
    USECASE_AUDIO_HFP_SCO,
@@ -381,6 +382,13 @@ struct audio_device {


    void *adm_data;
    void *adm_data;
    void *adm_lib;
    void *adm_lib;

    struct pcm_config haptics_config;
    struct pcm *haptic_pcm;
    int    haptic_pcm_device_id;
    uint8_t *haptic_buffer;
    size_t haptic_buffer_size;

    adm_init_t adm_init;
    adm_init_t adm_init;
    adm_deinit_t adm_deinit;
    adm_deinit_t adm_deinit;
    adm_register_input_stream_t adm_register_input_stream;
    adm_register_input_stream_t adm_register_input_stream;
+5 −0
Original line number Original line Diff line number Diff line
@@ -1401,6 +1401,11 @@ int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
    return device_id;
    return device_id;
}
}


int platform_get_haptics_pcm_device_id()
{
    return -1;
}

static int find_index(struct name_to_index * table, int32_t len, const char * name)
static int find_index(struct name_to_index * table, int32_t len, const char * name)
{
{
    int ret = 0;
    int ret = 0;
+5 −0
Original line number Original line Diff line number Diff line
@@ -424,6 +424,11 @@ int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
    return device_id;
    return device_id;
}
}


int platform_get_haptics_pcm_device_id()
{
    return -1;
}

int platform_get_snd_device_index(char *snd_device_index_name __unused)
int platform_get_snd_device_index(char *snd_device_index_name __unused)
{
{
    return -ENODEV;
    return -ENODEV;
+30 −1
Original line number Original line Diff line number Diff line
@@ -184,6 +184,8 @@ struct platform_data {
static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
                                            DEEP_BUFFER_PCM_DEVICE},
                                            DEEP_BUFFER_PCM_DEVICE},
    [USECASE_AUDIO_PLAYBACK_WITH_HAPTICS] = {AUDIO_HAPTICS_PCM_DEVICE,
                                             AUDIO_HAPTICS_PCM_DEVICE},
    [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
    [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
                                            LOWLATENCY_PCM_DEVICE},
                                            LOWLATENCY_PCM_DEVICE},
    [USECASE_AUDIO_PLAYBACK_HIFI] = {MULTIMEDIA2_PCM_DEVICE,
    [USECASE_AUDIO_PLAYBACK_HIFI] = {MULTIMEDIA2_PCM_DEVICE,
@@ -293,6 +295,7 @@ static const char * const device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] = "speaker-safe-and-bt-sco",
    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] = "speaker-safe-and-bt-sco",
    [SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB] = "speaker-and-bt-sco-wb",
    [SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB] = "speaker-and-bt-sco-wb",
    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] = "speaker-safe-and-bt-sco-wb",
    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] = "speaker-safe-and-bt-sco-wb",
    [SND_DEVICE_OUT_VOICE_HEARING_AID] = "hearing-aid",


    /* Capture sound devices */
    /* Capture sound devices */
    [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
    [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
@@ -372,6 +375,7 @@ static const char * const device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = "camcorder-mic",
    [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = "camcorder-mic",
    [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
    [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
    [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
    [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
    [SND_DEVICE_IN_VOICE_HEARING_AID] = "hearing-aid-mic",
};
};


static struct audio_effect_config \
static struct audio_effect_config \
@@ -444,6 +448,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
    [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
    [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
    [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
    [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = ACDB_ID_VOICE_SPEAKER,
    [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = ACDB_ID_VOICE_SPEAKER,
    [SND_DEVICE_OUT_VOICE_HEARING_AID] = 45,


    [SND_DEVICE_IN_HANDSET_MIC] = 4,
    [SND_DEVICE_IN_HANDSET_MIC] = 4,
    [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
    [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
@@ -521,6 +526,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = {
    [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = 61,
    [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = 61,
    [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 129,
    [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 129,
    [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
    [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
    [SND_DEVICE_IN_VOICE_HEARING_AID] = 44,
};
};


// Platform specific backend bit width table
// Platform specific backend bit width table
@@ -579,6 +585,7 @@ static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET_SPEC)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET_SPEC)},
    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEARING_AID)},


    /* in */
    /* in */
    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
@@ -655,6 +662,8 @@ static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE)},
    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE)},
    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE)},
    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE)},
    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT)},
    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT)},
    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEARING_AID)},

    /* For legacy xml file parsing */
    /* For legacy xml file parsing */
    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
@@ -667,6 +676,7 @@ static char * hw_interface_table[SND_DEVICE_MAX] = {0};
static const struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
static const struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_WITH_HAPTICS)},
    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_HIFI)},
    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_HIFI)},
    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_TTS)},
    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_TTS)},
@@ -1285,6 +1295,7 @@ static void set_platform_defaults(struct platform_data * my_data)
    backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
    backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
    backend_tag_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] = strdup("speaker-safe-and-bt-a2dp");
    backend_tag_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] = strdup("speaker-safe-and-bt-a2dp");
    backend_tag_table[SND_DEVICE_OUT_USB_HEADSET_SPEC] = strdup("usb-headset");
    backend_tag_table[SND_DEVICE_OUT_USB_HEADSET_SPEC] = strdup("usb-headset");
    backend_tag_table[SND_DEVICE_OUT_VOICE_HEARING_AID] = strdup("hearing-aid");


    hw_interface_table[SND_DEVICE_OUT_HANDSET] = strdup("SLIMBUS_0_RX");
    hw_interface_table[SND_DEVICE_OUT_HANDSET] = strdup("SLIMBUS_0_RX");
    hw_interface_table[SND_DEVICE_OUT_SPEAKER] = strdup("SLIMBUS_0_RX");
    hw_interface_table[SND_DEVICE_OUT_SPEAKER] = strdup("SLIMBUS_0_RX");
@@ -1333,6 +1344,11 @@ static void set_platform_defaults(struct platform_data * my_data)
    hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB] = strdup("SLIMBUS_0_RX-and-SEC_AUX_PCM_RX");
    hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB] = strdup("SLIMBUS_0_RX-and-SEC_AUX_PCM_RX");
    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] = strdup("QUAT_TDM_RX_0-and-SLIMBUS_7_RX"),
    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] = strdup("QUAT_TDM_RX_0-and-SLIMBUS_7_RX"),
    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] = strdup("QUAT_TDM_RX_0-and-SLIMBUS_7_RX"),
    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] = strdup("QUAT_TDM_RX_0-and-SLIMBUS_7_RX"),
    /* So far, primary hal doesn't support hearing aid device.
       Need snd_device to route voice call and use specific acdb tuning.
       Also, BT_RX is a virtual port to indicate bluetooth hearing aid. */
    hw_interface_table[SND_DEVICE_OUT_VOICE_HEARING_AID] = strdup("BT_RX"),

    hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
    hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
    hw_interface_table[SND_DEVICE_IN_VOICE_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
    hw_interface_table[SND_DEVICE_IN_VOICE_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
    hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MIC_AEC] =  strdup("USB_AUDIO_TX");
    hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MIC_AEC] =  strdup("USB_AUDIO_TX");
@@ -1400,6 +1416,8 @@ static void set_platform_defaults(struct platform_data * my_data)
    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = strdup("SLIMBUS_0_TX");
    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = strdup("SLIMBUS_0_TX");
    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = strdup("SLIMBUS_0_TX");
    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = strdup("SLIMBUS_0_TX");
    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = strdup("SLIMBUS_0_TX");
    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = strdup("SLIMBUS_0_TX");
    hw_interface_table[SND_DEVICE_IN_VOICE_HEARING_AID] = strdup("SLIMBUS_0_TX");

    my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
    my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
}
}


@@ -2060,6 +2078,11 @@ int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
    return device_id;
    return device_id;
}
}


int platform_get_haptics_pcm_device_id()
{
    return HAPTICS_PCM_DEVICE;
}

static int find_index(const struct name_to_index * table, int32_t len,
static int find_index(const struct name_to_index * table, int32_t len,
                      const char * name)
                      const char * name)
{
{
@@ -2893,8 +2916,11 @@ snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devi
                snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
                snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
            else
            else
                snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
                snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
        } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
        } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX) {
            snd_device = SND_DEVICE_OUT_VOICE_TX;
            snd_device = SND_DEVICE_OUT_VOICE_TX;
        } else if (devices & AUDIO_DEVICE_OUT_HEARING_AID) {
            snd_device = SND_DEVICE_OUT_VOICE_HEARING_AID;
        }


        if (snd_device != SND_DEVICE_NONE) {
        if (snd_device != SND_DEVICE_NONE) {
            goto exit;
            goto exit;
@@ -3186,6 +3212,8 @@ snd_device_t platform_get_input_snd_device(void *platform,
                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
                }
                }
            }
            }
        } else if (out_device & AUDIO_DEVICE_OUT_HEARING_AID) {
            snd_device = SND_DEVICE_IN_VOICE_HEARING_AID;
        }
        }
    } else if (source == AUDIO_SOURCE_CAMCORDER) {
    } else if (source == AUDIO_SOURCE_CAMCORDER) {
        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
@@ -3702,6 +3730,7 @@ int64_t platform_render_latency(audio_usecase_t usecase)
        case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
        case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
            return DEEP_BUFFER_PLATFORM_DELAY;
            return DEEP_BUFFER_PLATFORM_DELAY;
        case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
        case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
        case USECASE_AUDIO_PLAYBACK_WITH_HAPTICS:
            return LOW_LATENCY_PLATFORM_DELAY;
            return LOW_LATENCY_PLATFORM_DELAY;
        case USECASE_AUDIO_PLAYBACK_ULL:
        case USECASE_AUDIO_PLAYBACK_ULL:
            return ULL_PLATFORM_DELAY;
            return ULL_PLATFORM_DELAY;
Loading