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

Commit ef735d63 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "audio: hal: support audio zoom interface for qdsp"

parents f958e4bd 20fb6d8f
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -340,6 +340,12 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_GCOV)),true)
    LOCAL_STATIC_LIBRARIES += libprofile_rt
endif

ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AUDIO_ZOOM)), true)
    LOCAL_CFLAGS += -DAUDIOZOOM_QDSP_ENABLED
    LOCAL_SRC_FILES += audio_extn/audiozoom.c
endif


#ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AUTO_HAL)),true)
#    LOCAL_CFLAGS += -DAUDIO_EXTN_AUTO_HAL_ENABLED
#    LOCAL_SRC_FILES += audio_extn/auto_hal.c
+260 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "audio_hw_audiozoom"
/*#define LOG_NDEBUG 0*/

#include <errno.h>
#include <log/log.h>
#include <stdlib.h>
#include <expat.h>
#include <audio_hw.h>
#include <system/audio.h>
#include <platform_api.h>
#include "audio_extn.h"

#include "audiozoom.h"

#include <resolv.h>

#define AUDIOZOOM_PRESET_FILE "/vendor/etc/audiozoom.xml"
#define MIN_BUFSIZE 8

typedef struct qdsp_audiozoom_cfg {
    uint32_t             topo_id;
    uint32_t             module_id;
    uint32_t             instance_id;
    uint32_t             zoom_param_id;
    uint32_t             wide_param_id;
    uint32_t             dir_param_id;
    uint32_t             app_type;
} qdsp_audiozoom_cfg_t;

static qdsp_audiozoom_cfg_t qdsp_audiozoom;

static void start_tag(void *userdata __unused, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    uint32_t index = 0;

    if (!attr) {
        ALOGE("%s: NULL platform/tag_name/attr", __func__);
        return;
    }

    if (strcmp(tag_name, "topo") == 0) {
        if (strcmp(attr[0], "id") == 0) {
            if (attr[1])
                qdsp_audiozoom.topo_id = atoi(attr[1]);
        }
    } else if (strcmp(tag_name, "module") == 0) {
        if (strcmp(attr[0], "id") == 0) {
            if (attr[1])
                qdsp_audiozoom.module_id = atoi(attr[1]);
        }
    } else if (strcmp(tag_name, "param") == 0) {
        while (attr[index] != NULL) {
            if (strcmp(attr[index], "zoom_id") == 0) {
                index++;
                if (attr[index])
                    qdsp_audiozoom.zoom_param_id = atoi(attr[index]);
                else
                    break;
            } else if (strcmp(attr[index], "wide_id") == 0) {
                index++;
                if (attr[index])
                    qdsp_audiozoom.wide_param_id = atoi(attr[index]);
                else
                    break;
            } else if (strcmp(attr[index], "dir_id") == 0) {
                index++;
                if (attr[index])
                    qdsp_audiozoom.dir_param_id = atoi(attr[index]);
                else
                    break;
            }
            index++;
        }
    } else if (strcmp(tag_name, "app_type") == 0) {
        if (strcmp(attr[0], "id") == 0) {
            if (attr[1])
                qdsp_audiozoom.app_type = atoi(attr[1]);
        }
    } else if (strcmp(tag_name, "instance") == 0) {
        if (strcmp(attr[0], "id") == 0) {
            if (attr[1])
                qdsp_audiozoom.instance_id = atoi(attr[1]);
        }
    } else {
        ALOGE("%s: %s is not a supported tag", __func__, tag_name);
    }

    return;
}

static void end_tag(void *userdata __unused, const XML_Char *tag_name)
{
    if (strcmp(tag_name, "topo") == 0) {
    } else if (strcmp(tag_name, "module") == 0) {
    } else if (strcmp(tag_name, "param") == 0) {
    } else if (strcmp(tag_name, "app_type") == 0) {
    } else if (strcmp(tag_name, "instance") == 0) {
    } else {
        ALOGE("%s: %s is not a supported tag", __func__, tag_name);
    }
}

static int audio_extn_audiozoom_parse_info(const char *filename)
{
    XML_Parser      parser;
    FILE            *file;
    int             ret = 0;
    int             bytes_read;
    void            *buf;
    static const uint32_t kBufSize = 1024;

    file = fopen(filename, "r");
    if (!file) {
        ALOGE("%s: Failed to open %s", __func__, filename);
        ret = -ENODEV;
        goto done;
    }

    parser = XML_ParserCreate(NULL);
    if (!parser) {
        ALOGE("%s: Failed to create XML parser!", __func__);
        ret = -ENODEV;
        goto err_close_file;
    }

    XML_SetElementHandler(parser, start_tag, end_tag);

    while (1) {
        buf = XML_GetBuffer(parser, kBufSize);
        if (buf == NULL) {
            ALOGE("%s: XML_GetBuffer failed", __func__);
            ret = -ENOMEM;
            goto err_free_parser;
        }

        bytes_read = fread(buf, 1, kBufSize, file);
        if (bytes_read < 0) {
            ALOGE("%s: fread failed, bytes read = %d", __func__, bytes_read);
             ret = bytes_read;
            goto err_free_parser;
        }

        if (XML_ParseBuffer(parser, bytes_read,
                            bytes_read == 0) == XML_STATUS_ERROR) {
            ALOGE("%s: XML_ParseBuffer failed, for %s",
                __func__, filename);
            ret = -EINVAL;
            goto err_free_parser;
        }

        if (bytes_read == 0)
            break;
    }

err_free_parser:
    XML_ParserFree(parser);
err_close_file:
    fclose(file);
done:
    return ret;
}

int audio_extn_audiozoom_set_microphone_direction(
    struct stream_in *in, audio_microphone_direction_t dir)
{
    (void)in;
    (void)dir;
    return 0;
}

static int audio_extn_audiozoom_set_microphone_field_dimension_zoom(
    struct stream_in *in, float zoom)
{
    struct audio_device *adev = in->dev;
    struct str_parms *parms = str_parms_create();
    uint8_t value[MIN_BUFSIZE] = {0};
    char data[MIN_BUFSIZE * 2] = {0};
    int32_t ret;

    if (zoom > 1.0 || zoom < 0)
        return -EINVAL;

    if (qdsp_audiozoom.topo_id == 0 || qdsp_audiozoom.module_id == 0 ||
        qdsp_audiozoom.zoom_param_id == 0)
        return -ENOSYS;

    str_parms_add_int(parms, "cal_devid", in->device);
    str_parms_add_int(parms, "cal_apptype", in->app_type_cfg.app_type);
    str_parms_add_int(parms, "cal_topoid", qdsp_audiozoom.topo_id);
    str_parms_add_int(parms, "cal_moduleid", qdsp_audiozoom.module_id);
    str_parms_add_int(parms, "cal_instanceid", qdsp_audiozoom.instance_id);
    str_parms_add_int(parms, "cal_paramid", qdsp_audiozoom.zoom_param_id);

    zoom *= 255;
    value[0] = (uint8_t) zoom; /* Valid value is 0 to 255 */

    ret = b64_ntop(value, sizeof(value), data, sizeof(data));
    if (ret > 0) {
        str_parms_add_str(parms, "cal_data", data);

        platform_set_parameters(adev->platform, parms);
    } else {
        ALOGE("%s: failed to convert data to string, ret %d", __func__, ret);
    }

    str_parms_destroy(parms);

    return 0;
}

static int audio_extn_audiozoom_set_microphone_field_dimension_wide_angle(
    struct stream_in *in, float zoom)
{
    (void)in;
    (void)zoom;
    return 0;
}

int audio_extn_audiozoom_set_microphone_field_dimension(
    struct stream_in *in, float zoom)
{
    if (zoom > 1.0 || zoom < -1.0)
        return -EINVAL;

    if (zoom >= 0 && zoom <= 1.0)
        return audio_extn_audiozoom_set_microphone_field_dimension_zoom(in, zoom);

    if (zoom >= -1.0 && zoom <= 0)
        return audio_extn_audiozoom_set_microphone_field_dimension_wide_angle(in, zoom);

    return 0;
}

int audio_extn_audiozoom_init()
{
    audio_extn_audiozoom_parse_info(AUDIOZOOM_PRESET_FILE);

    ALOGV("%s: topo_id=%d, module_id=%d, instance_id=%d, zoom__id=%d, dir_id=%d, app_type=%d",
        __func__, qdsp_audiozoom.topo_id, qdsp_audiozoom.module_id, qdsp_audiozoom.instance_id,
        qdsp_audiozoom.zoom_param_id, qdsp_audiozoom.dir_param_id,qdsp_audiozoom.app_type);

    return 0;
}
+31 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef AUDIOZOOM_H_
#define AUDIOZOOM_H_

#ifndef AUDIOZOOM_QDSP_ENABLED
#define audio_extn_audiozoom_init()                                          (0)
#define audio_extn_audiozoom_set_microphone_direction(stream, dir)           (-ENOSYS)
#define audio_extn_audiozoom_set_microphone_field_dimension(stream, zoom)    (-ENOSYS)
#else
int audio_extn_audiozoom_init();
int audio_extn_audiozoom_set_microphone_direction(struct stream_in *stream,
                                           audio_microphone_direction_t dir);
int audio_extn_audiozoom_set_microphone_field_dimension(struct stream_in *stream, float zoom);
#endif

#endif /* AUDIOZOOM_H_ */
+34 −8
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@
#include "voice_extn.h"
#include "ip_hdlr_intf.h"
#include "audio_feature_manager.h"
#include "audio_extn/audiozoom.h"

#include "sound/compress_params.h"
#include "sound/asound.h"
@@ -506,6 +507,11 @@ static void enable_gcov()
}
#endif

static int in_set_microphone_direction(const struct audio_stream_in *stream,
                                           audio_microphone_direction_t dir);
static int in_set_microphone_field_dimension(const struct audio_stream_in *stream, float zoom);


static bool may_use_noirq_mode(struct audio_device *adev, audio_usecase_t uc_id,
                               int flags __unused)
{
@@ -2761,6 +2767,8 @@ int start_input_stream(struct stream_in *in)
    }

    check_and_enable_effect(adev);
    audio_extn_audiozoom_set_microphone_direction(in, in->zoom);
    audio_extn_audiozoom_set_microphone_field_dimension(in, in->direction);

done_open:
    audio_extn_perf_lock_release(&adev->perf_lock_handle);
@@ -4375,17 +4383,32 @@ error:

static int in_set_microphone_direction(const struct audio_stream_in *stream,
                                           audio_microphone_direction_t dir) {
    (void)stream;
    (void)dir;
    ALOGVV("%s", __func__);
    return -ENOSYS;
    struct stream_in *in = (struct stream_in *)stream;

    ALOGVV("%s: standby %d source %d dir %d", __func__, in->standby, in->source, dir);

    in->direction = dir;

    if (in->standby)
        return 0;

    return audio_extn_audiozoom_set_microphone_direction(in, dir);
}

static int in_set_microphone_field_dimension(const struct audio_stream_in *stream, float zoom) {
    (void)stream;
    (void)zoom;
    ALOGVV("%s", __func__);
    return -ENOSYS;
    struct stream_in *in = (struct stream_in *)stream;

    ALOGVV("%s: standby %d source %d zoom %f", __func__, in->standby, in->source, zoom);

    if (zoom > 1.0 || zoom < -1.0)
        return -EINVAL;

    in->zoom = zoom;

    if (in->standby)
        return 0;

    return audio_extn_audiozoom_set_microphone_field_dimension(in, zoom);
}


@@ -8095,6 +8118,8 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
    in->flags = flags;
    in->bit_width = 16;
    in->af_period_multiplier = 1;
    in->direction = MIC_DIRECTION_UNSPECIFIED;
    in->zoom = 0;

    ALOGV("%s: source = %d, config->channel_mask = %d", __func__, source, config->channel_mask);
    if (source == AUDIO_SOURCE_VOICE_UPLINK ||
@@ -9155,6 +9180,7 @@ static int adev_open(const hw_module_t *module, const char *name,
    adev->is_charging = audio_extn_battery_properties_is_charging();
    audio_extn_sound_trigger_init(adev); /* dependent on snd_mon_init() */
    audio_extn_sound_trigger_update_battery_status(adev->is_charging);
    audio_extn_audiozoom_init();
    pthread_mutex_unlock(&adev->lock);
    /* Allocate memory for Device config params */
    adev->device_cfg_params = (struct audio_device_config_param*)
+2 −0
Original line number Diff line number Diff line
@@ -409,6 +409,8 @@ struct stream_in {
    struct audio_device *dev;
    card_status_t card_status;
    int capture_started;
    float zoom;
    audio_microphone_direction_t direction;

    /* Array of supported channel mask configurations. +1 so that the last entry is always 0 */
    audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];