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

Commit 74a314b7 authored by stenkinevgeniy's avatar stenkinevgeniy
Browse files

Audio: update hal, add mixer pcmdai parser

parent 91b7c7ba
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -25,7 +25,8 @@ LOCAL_SRC_FILES := \
	audio_hw.c \
	compress_offload.c \
	ril_interface.c \
	voice.c
	voice.c \
        mixer_util.c

# TODO: remove resampler if possible when AudioFlinger supports downsampling from 48 to 8
LOCAL_SHARED_LIBRARIES := \
@@ -37,7 +38,8 @@ LOCAL_SHARED_LIBRARIES := \
	libtinycompress \
	libaudioroute \
	libdl \
	libsecril-client
	libsecril-client \
        libexpat


LOCAL_C_INCLUDES += \
@@ -48,11 +50,11 @@ LOCAL_C_INCLUDES += \
	hardware/samsung/ril/libsecril-client \
	$(call include-path-for, audio-utils) \
	$(call include-path-for, audio-route) \
	$(call include-path-for, audio-effects)
	$(call include-path-for, audio-effects) \
        external/expat/lib

LOCAL_CFLAGS := -Werror -Wall
LOCAL_CFLAGS := -Wall
#LOCAL_CFLAGS += -DPREPROCESSING_ENABLED
#LOCAL_CFLAGS += -DHW_AEC_LOOPBACK

LOCAL_MODULE := audio.primary.$(TARGET_BOOTLOADER_BOARD_NAME)

+757 −328

File changed.

Preview size limit exceeded, changes collapsed.

+36 −14
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Android Open Source Project
 * Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
 * Copyright (C) 2018 The LineageOS Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -186,6 +187,9 @@ typedef enum {
    USECASE_AUDIO_CAPTURE,

    USECASE_VOICE_CALL,

    USECASE_BT_SCO,
    USECASE_FM_RADIO,
    AUDIO_USECASE_MAX
} audio_usecase_t;

@@ -227,14 +231,28 @@ struct offload_cmd {
    int             data[];
};

struct pcm_device_profile {
    struct pcm_config config;
    int               card;
    int               id;
    usecase_type_t    type;
    audio_devices_t   devices;
};

struct pcm_device {
    struct listnode            stream_list_node;
    struct pcm_device_profile* pcm_profile;
    struct pcm*                pcm;
    int                        status;
};

struct stream_out {
    struct audio_stream_out     stream;
    pthread_mutex_t             lock; /* see note below on mutex acquisition order */
    pthread_mutex_t             pre_lock; /* acquire before lock to avoid DOS by playback thread */
    pthread_cond_t              cond;
    struct pcm_config           config;
    int                         pcm_device_id;
    struct pcm                  *pcm;
    struct listnode             pcm_dev_list;
    struct compr_config         compr_config;
    struct compress*            compr;
    int                         standby;
@@ -285,8 +303,7 @@ struct stream_in {
    pthread_mutex_t                     pre_lock; /* acquire before lock to avoid DOS by
                                                     capture thread */
    struct pcm_config                   config;
    struct pcm                          *pcm;
    int                                 pcm_device_id;
    struct listnode                     pcm_dev_list;
    int                                 standby;
    audio_source_t                      source;
    audio_devices_t                     devices;
@@ -315,13 +332,6 @@ struct stream_in {
    int16_t *ref_buf;
    size_t ref_buf_size;
    size_t ref_buf_frames;

#ifdef HW_AEC_LOOPBACK
    bool hw_echo_reference;
    int16_t* hw_ref_buf;
    size_t hw_ref_buf_size;
#endif

    int num_preprocessors;
    struct effect_info_s preprocessors[MAX_PREPROCESSORS];

@@ -337,6 +347,15 @@ struct stream_in {
                                                        entering standby */
};

struct mixer_card {
    struct listnode     adev_list_node;
    struct listnode     uc_list_node[AUDIO_USECASE_MAX];
    int                 card;
    struct mixer*       mixer;
    struct audio_route* audio_route;
    struct timespec     dsp_poweroff_time;
};

struct audio_usecase {
    struct listnode         adev_list_node;
    audio_usecase_t         id;
@@ -345,6 +364,7 @@ struct audio_usecase {
    snd_device_t            out_snd_device;
    snd_device_t            in_snd_device;
    struct audio_stream*    stream;
    struct listnode         mixer_list;
};

struct voice_data {
@@ -358,12 +378,10 @@ struct voice_data {
struct audio_device {
    struct audio_hw_device  device;
    pthread_mutex_t         lock; /* see note below on mutex acquisition order */
    struct mixer            *mixer;
    struct audio_route      *audio_route;
    struct listnode         mixer_list;
    audio_mode_t            mode;
    struct stream_in*       active_input;
    struct stream_out*      primary_output;
    struct stream_out*      current_call_output;
    bool                    mic_mute;
    bool                    screen_off;

@@ -393,6 +411,10 @@ struct audio_device {
    amplifier_device_t      *amp;
};

/* From platform_info.c */
int init_pcm_ids();
int get_pcm_device_id(audio_usecase_t usecase, usecase_type_t type);

/*
 * NOTE: when multiple mutexes have to be acquired, always take the
 * lock_inputs, stream_in, stream_out, then audio_device mutex.
+0 −3
Original line number Diff line number Diff line
@@ -54,9 +54,6 @@
#endif
#endif

#define MIXER_PATH_MAX_LENGTH 100
#define MIXER_XML_PATH "mixer_paths_0.xml"

/* Unusupported
#define SOUND_CAPTURE_LOOPBACK_AEC_DEVICE 1
#define SOUND_CAPTURE_HOTWORD_DEVICE 0

audio/mixer_util.c

0 → 100644
+174 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The LineageOS 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 "mixer_util"
#define LOG_NDEBUG 0

#include <errno.h>
#include <stdio.h>
#include <expat.h>
#include <cutils/log.h>
#include <audio_hw.h>
#include <math.h>
#include <mixer_util.h>
#include <samsung_audio.h>


/* init with default ids, but updated while parsing mixer xml */
int pcm_device_table[AUDIO_USECASE_MAX][2] = {
    [USECASE_AUDIO_PLAYBACK] = {SOUND_PLAYBACK_DEVICE, SOUND_PLAYBACK_DEVICE},
    [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {-1, -1},
    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {SOUND_DEEP_BUFFER_DEVICE, SOUND_DEEP_BUFFER_DEVICE},
    [USECASE_AUDIO_CAPTURE] = {SOUND_CAPTURE_DEVICE, SOUND_CAPTURE_DEVICE},
    [USECASE_BT_SCO] = {SOUND_PLAYBACK_SCO_DEVICE, SOUND_PLAYBACK_SCO_DEVICE},
    [USECASE_FM_RADIO] = {-1, -1},
    [USECASE_VOICE_CALL] = {SOUND_PLAYBACK_VOICE_DEVICE, SOUND_CAPTURE_VOICE_DEVICE},
};

static const char * const uc_pcmdai_table[AUDIO_USECASE_MAX] = {

    [USECASE_AUDIO_PLAYBACK] = "playback_link",
    [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "none",
    [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "playback_offload_link",
    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "playback_deep_link",
    [USECASE_AUDIO_CAPTURE] = "capture_link",
    [USECASE_BT_SCO] = "bluetooth_link",
    [USECASE_FM_RADIO] = "fmradio_link",
    [USECASE_VOICE_CALL] = "baseband_link",
};

int get_pcm_device_id(audio_usecase_t usecase, usecase_type_t type)
{
    if (type == PCM_PLAYBACK)
        return pcm_device_table[usecase][0];
    else
        return pcm_device_table[usecase][1];
}

static void process_pcmdai(const XML_Char **attr)
{
    int i;

    for (i=0; i < AUDIO_USECASE_MAX; i++) {
         if (strcmp(attr[0], uc_pcmdai_table[i])==0) {
             ALOGV("%s: found %s = %d", __func__,uc_pcmdai_table[i],atoi((char *)attr[1]));
             pcm_device_table[i][0] = atoi((char *)attr[1]);
             pcm_device_table[i][1] = atoi((char *)attr[1]);
         }
    }

    /* extended capture links, usually equal with same playback links*/

    if (strcmp(attr[0], "baseband_capture_link")==0) {
        ALOGV("%s: found %s id =%d", __func__,"baseband_capture_link",atoi((char *)attr[1]));
        pcm_device_table[USECASE_VOICE_CALL][1] = atoi((char *)attr[1]);
    }

    if (strcmp(attr[0], "bluetooth_capture_link")==0) {
        ALOGV("%s: found %s id =%d", __func__,"bluetooth_capture_link",atoi((char *)attr[1]));
        pcm_device_table[USECASE_BT_SCO][1] = atoi((char *)attr[1]);
    }


    return;
}


static void start_tag(void *userdata __unused, const XML_Char *tag_name,
                      const XML_Char **attr)
{

    if (strcmp(tag_name, "pcmdai") == 0) {
        process_pcmdai(attr);
    }
    return;
}

static void end_tag(void *userdata __unused, const XML_Char *tag_name __unused)
{
}

int init_pcm_ids(const char *filename)
{
    XML_Parser      parser;
    FILE            *file;
    int             ret = 0;
    int             bytes_read;
    void            *buf;
    static const uint32_t kBufSize = 1024;
    char   mixer_file_name[MIXER_PATH_MAX_LENGTH]= {0};

    if (filename == NULL) {
        strlcpy(mixer_file_name, MIXER_PATH_DEFAULT, MIXER_PATH_MAX_LENGTH);
    } else {
        strlcpy(mixer_file_name, filename, MIXER_PATH_MAX_LENGTH);
    }

    ALOGV("%s: mixer file name is %s", __func__, mixer_file_name);

    file = fopen(mixer_file_name, "r");

    if (!file) {
        ALOGD("%s: Failed to open %s, using defaults.",
            __func__, mixer_file_name);
        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__, mixer_file_name);
            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;
}
Loading