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

Commit 27455110 authored by Dhananjay Kumar's avatar Dhananjay Kumar Committed by Steve Kondik
Browse files

hal: Add support for listen playback concurrency

Add support for concurrency handling between number of
listen capture session and playback activity.

Change-Id: I4a0656f240c62f2cc6266a714a96fdcdc13ae9d8
parent 74b7909b
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -144,18 +144,23 @@ void hw_info_append_hw_type(void *hw_info, snd_device_t snd_device,
#ifndef AUDIO_LISTEN_ENABLED
#define audio_extn_listen_init(adev, snd_card)                  (0)
#define audio_extn_listen_deinit(adev)                          (0)
#define audio_extn_listen_update_status(uc_info, event)         (0)
#define audio_extn_listen_update_device_status(snd_dev, event)  (0)
#define audio_extn_listen_update_stream_status(uc_info, event)  (0)
#define audio_extn_listen_set_parameters(adev, parms)           (0)
#else
enum listen_event_type {
    LISTEN_EVENT_SND_DEVICE_FREE,
    LISTEN_EVENT_SND_DEVICE_BUSY
    LISTEN_EVENT_SND_DEVICE_BUSY,
    LISTEN_EVENT_STREAM_FREE,
    LISTEN_EVENT_STREAM_BUSY
};
typedef enum listen_event_type listen_event_type_t;

int audio_extn_listen_init(struct audio_device *adev, unsigned int snd_card);
void audio_extn_listen_deinit(struct audio_device *adev);
void audio_extn_listen_update_status(snd_device_t snd_device,
void audio_extn_listen_update_device_status(snd_device_t snd_device,
                                     listen_event_type_t event);
void audio_extn_listen_update_stream_status(struct audio_usecase *uc_info,
                                     listen_event_type_t event);
void audio_extn_listen_set_parameters(struct audio_device *adev,
                                      struct str_parms *parms);
+64 −14
Original line number Diff line number Diff line
@@ -95,25 +95,75 @@ struct listen_audio_device {

static struct listen_audio_device *listen_dev;

void audio_extn_listen_update_status(snd_device_t snd_device,
void audio_extn_listen_update_device_status(snd_device_t snd_device,
                                     listen_event_type_t event)
{
    if (!platform_listen_update_status(snd_device)) {
        ALOGV("%s(): no need to notify listen. device = %s. Event = %u",
                __func__, platform_get_snd_device_name(snd_device), event);
    bool raise_event = false;
    int device_type = -1;

    if (snd_device >= SND_DEVICE_OUT_BEGIN &&
        snd_device < SND_DEVICE_OUT_END)
        device_type = PCM_PLAYBACK;
    else if (snd_device >= SND_DEVICE_IN_BEGIN &&
        snd_device < SND_DEVICE_IN_END)
        device_type = PCM_CAPTURE;
    else {
        ALOGE("%s: invalid device 0x%x, for event %d",
                           __func__, snd_device, event);
        return;
    }

    if (listen_dev) {
        ALOGI("%s(): %s listen. current active device = %s. Event = %u",
                __func__,
                (event == LISTEN_EVENT_SND_DEVICE_BUSY) ? "stop" : "start",
                platform_get_snd_device_name(snd_device), event);

            if (event == LISTEN_EVENT_SND_DEVICE_FREE)
                   listen_dev->notify_event(AUDIO_CAPTURE_INACTIVE);
            else if (event == LISTEN_EVENT_SND_DEVICE_BUSY)
                   listen_dev->notify_event(AUDIO_CAPTURE_ACTIVE);
        raise_event = platform_listen_device_needs_event(snd_device);
        ALOGI("%s(): device 0x%x of type %d for Event %d, with Raise=%d",
            __func__, snd_device, device_type, event, raise_event);
        if (raise_event && (device_type == PCM_CAPTURE)) {
            switch(event) {
            case LISTEN_EVENT_SND_DEVICE_FREE:
                listen_dev->notify_event(AUDIO_DEVICE_IN_INACTIVE);
                break;
            case LISTEN_EVENT_SND_DEVICE_BUSY:
                listen_dev->notify_event(AUDIO_DEVICE_IN_ACTIVE);
                break;
            default:
                ALOGW("%s:invalid event %d for device 0x%x",
                                      __func__, event, snd_device);
            }
        }/*Events for output device, if required can be placed here in else*/
    }
}

void audio_extn_listen_update_stream_status(struct audio_usecase *uc_info,
                                     listen_event_type_t event)
{
    bool raise_event = false;
    audio_usecase_t uc_id;
    int usecase_type = -1;

    if (uc_info == NULL) {
        ALOGE("%s: usecase is NULL!!!", __func__);
        return;
    }
    uc_id = uc_info->id;
    usecase_type = uc_info->type;

    if (listen_dev) {
        raise_event = platform_listen_usecase_needs_event(uc_id);
        ALOGI("%s(): uc_id %d of type %d for Event %d, with Raise=%d",
            __func__, uc_id, usecase_type, event, raise_event);
        if (raise_event && (usecase_type == PCM_PLAYBACK)) {
            switch(event) {
            case LISTEN_EVENT_STREAM_FREE:
                listen_dev->notify_event(AUDIO_STREAM_OUT_INACTIVE);
                break;
            case LISTEN_EVENT_STREAM_BUSY:
                listen_dev->notify_event(AUDIO_STREAM_OUT_ACTIVE);
                break;
            default:
                ALOGW("%s:invalid event %d, for usecase %d",
                                      __func__, event, uc_id);
            }
        }/*Events for capture usecase, if required can be placed here in else*/
    }
}

+10 −4
Original line number Diff line number Diff line
@@ -402,6 +402,7 @@ int enable_audio_route(struct audio_device *adev,
    audio_extn_dolby_set_dmid(adev);
    audio_extn_dolby_set_endpoint(adev);
#endif
    audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_BUSY);
    strcpy(mixer_path, use_case_table[usecase->id]);
    platform_add_backend_name(mixer_path, snd_device);
    ALOGV("%s: apply mixer and update path: %s", __func__, mixer_path);
@@ -428,6 +429,7 @@ int disable_audio_route(struct audio_device *adev,
    platform_add_backend_name(mixer_path, snd_device);
    ALOGV("%s: reset and update mixer path: %s", __func__, mixer_path);
    audio_route_reset_and_update_path(adev->audio_route, mixer_path);
    audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_FREE);
    ALOGV("%s: exit", __func__);
    return 0;
}
@@ -473,12 +475,16 @@ int enable_snd_device(struct audio_device *adev,
    }  else {
        ALOGV("%s: snd_device(%d: %s)", __func__,
            snd_device, device_name);
        /* due to the possibility of calibration overwrite between listen
            and audio, notify listen hal before audio calibration is sent */
        audio_extn_listen_update_device_status(snd_device,
                                        LISTEN_EVENT_SND_DEVICE_BUSY);
        if (platform_send_audio_calibration(adev->platform, snd_device) < 0) {
            adev->snd_dev_ref_cnt[snd_device]--;
            audio_extn_listen_update_device_status(snd_device,
                                        LISTEN_EVENT_SND_DEVICE_FREE);
            return -EINVAL;
        }
        audio_extn_listen_update_status(snd_device,
                LISTEN_EVENT_SND_DEVICE_BUSY);

        audio_route_apply_and_update_path(adev->audio_route, device_name);
    }
@@ -524,7 +530,7 @@ int disable_snd_device(struct audio_device *adev,
        } else
            audio_route_reset_and_update_path(adev->audio_route, device_name);

        audio_extn_listen_update_status(snd_device,
        audio_extn_listen_update_device_status(snd_device,
                                        LISTEN_EVENT_SND_DEVICE_FREE);
    }

+7 −2
Original line number Diff line number Diff line
@@ -920,7 +920,12 @@ int platform_update_usecase_from_source(int source __unused,
    return usecase;
}

bool platform_listen_update_status(snd_device_t snd_device __unused)
bool platform_listen_device_needs_event(snd_device_t snd_device __unused)
{
    return false;
}

bool platform_listen_usecase_needs_event(audio_usecase_t uc_id)
{
    return false;
}
+11 −4
Original line number Diff line number Diff line
@@ -1959,16 +1959,23 @@ int platform_update_usecase_from_source(int source, int usecase)
    }
}

bool platform_listen_update_status(snd_device_t snd_device)
bool platform_listen_device_needs_event(snd_device_t snd_device)
{
    bool needs_event = false;

    if ((snd_device >= SND_DEVICE_IN_BEGIN) &&
        (snd_device < SND_DEVICE_IN_END) &&
#ifdef FM_ENABLED
        (snd_device != SND_DEVICE_IN_CAPTURE_FM) &&
#endif
        (snd_device != SND_DEVICE_IN_CAPTURE_VI_FEEDBACK))
        return true;
    else
        needs_event = true;

    return needs_event;
}

bool platform_listen_usecase_needs_event(audio_usecase_t uc_id __unused)
{
    return false;
}

Loading