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

Commit c777e8df authored by The Android Open Source Project's avatar The Android Open Source Project
Browse files

Merge commit '2c69188d' into HEAD

parents 02290055 2c69188d
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -7,6 +7,7 @@ include $(MY_LOCAL_PATH)/legacy/Android.mk
else
else
include $(MY_LOCAL_PATH)/hal/Android.mk
include $(MY_LOCAL_PATH)/hal/Android.mk
include $(MY_LOCAL_PATH)/voice_processing/Android.mk
include $(MY_LOCAL_PATH)/voice_processing/Android.mk
include $(MY_LOCAL_PATH)/visualizer/Android.mk
endif
endif


endif
endif
+12 −6
Original line number Original line Diff line number Diff line
@@ -6,27 +6,33 @@ include $(CLEAR_VARS)


LOCAL_ARM_MODE := arm
LOCAL_ARM_MODE := arm


AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
ifneq ($(filter msm8974 msm8226,$(TARGET_BOARD_PLATFORM)),)
  # B-family platform uses msm8974 code base
  AUDIO_PLATFORM = msm8974
endif

LOCAL_SRC_FILES := \
LOCAL_SRC_FILES := \
	audio_hw.c \
	audio_hw.c \
	edid.c
	$(AUDIO_PLATFORM)/platform.c


LOCAL_SHARED_LIBRARIES := \
LOCAL_SHARED_LIBRARIES := \
	liblog \
	liblog \
	libcutils \
	libcutils \
	libtinyalsa \
	libtinyalsa \
	libtinycompress \
	libaudioroute \
	libaudioroute \
	libdl
	libdl


ifeq ($(TARGET_BOARD_PLATFORM), msm8974)
LOCAL_CFLAGS += -DMSM8974
endif


LOCAL_C_INCLUDES += \
LOCAL_C_INCLUDES += \
	external/tinyalsa/include \
	external/tinyalsa/include \
	external/tinycompress/include \
	$(call include-path-for, audio-route) \
	$(call include-path-for, audio-route) \
	$(call include-path-for, audio-effects)
	$(call include-path-for, audio-effects) \
	$(LOCAL_PATH)/$(AUDIO_PLATFORM)


LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
LOCAL_MODULE := audio.primary.$(AUDIO_PLATFORM)


LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw


+809 −805

File changed.

Preview size limit exceeded, changes collapsed.

+62 −192
Original line number Original line Diff line number Diff line
@@ -14,93 +14,34 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#ifndef QCOM_AUDIO_HW_H
#define QCOM_AUDIO_HW_H

#include <cutils/list.h>
#include <hardware/audio.h>
#include <hardware/audio.h>
#include <hardware/audio_effect.h>
#include <audio_effects/effect_aec.h>
#include <audio_effects/effect_ns.h>


#include <tinyalsa/asoundlib.h>
#include <tinyalsa/asoundlib.h>
#include <tinycompress/tinycompress.h>


#include <audio_route/audio_route.h>
#include <audio_route/audio_route.h>


#define ACDB_DEV_TYPE_OUT 1
#define VISUALIZER_LIBRARY_PATH "/system/lib/soundfx/libqcomvisualizer.so"
#define ACDB_DEV_TYPE_IN 2

#define DUALMIC_CONFIG_NONE 0      /* Target does not contain 2 mics */
#define DUALMIC_CONFIG_ENDFIRE 1
#define DUALMIC_CONFIG_BROADSIDE 2

/*
 * Below are the devices for which is back end is same, SLIMBUS_0_RX.
 * All these devices are handled by the internal HW codec. We can
 * enable any one of these devices at any time
 */
#define AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND \
    (AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
     AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE)

/* Sound devices specific to the platform
 * The DEVICE_OUT_* and DEVICE_IN_* should be mapped to these sound
 * devices to enable corresponding mixer paths
 */
typedef enum {
    SND_DEVICE_NONE = 0,


    /* Playback devices */
/* Flags used to initialize acdb_settings variable that goes to ACDB library */
    SND_DEVICE_MIN,
#define DMIC_FLAG       0x00000002
    SND_DEVICE_OUT_BEGIN = SND_DEVICE_MIN,
#define TTY_MODE_OFF    0x00000010
    SND_DEVICE_OUT_HANDSET = SND_DEVICE_OUT_BEGIN,
#define TTY_MODE_FULL   0x00000020
    SND_DEVICE_OUT_SPEAKER,
#define TTY_MODE_VCO    0x00000040
    SND_DEVICE_OUT_SPEAKER_REVERSE,
#define TTY_MODE_HCO    0x00000080
    SND_DEVICE_OUT_HEADPHONES,
#define TTY_MODE_CLEAR  0xFFFFFF0F
    SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
    SND_DEVICE_OUT_VOICE_SPEAKER,
    SND_DEVICE_OUT_VOICE_HEADPHONES,
    SND_DEVICE_OUT_HDMI,
    SND_DEVICE_OUT_SPEAKER_AND_HDMI,
    SND_DEVICE_OUT_BT_SCO,
    SND_DEVICE_OUT_VOICE_HANDSET_TMUS,
    SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
    SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
    SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
    SND_DEVICE_OUT_END,


    /*
#define ACDB_DEV_TYPE_OUT 1
     * Note: IN_BEGIN should be same as OUT_END because total number of devices
#define ACDB_DEV_TYPE_IN 2
     * SND_DEVICES_MAX should not exceed MAX_RX + MAX_TX devices.
     */
    /* Capture devices */
    SND_DEVICE_IN_BEGIN = SND_DEVICE_OUT_END,
    SND_DEVICE_IN_HANDSET_MIC  = SND_DEVICE_IN_BEGIN,
    SND_DEVICE_IN_SPEAKER_MIC,
    SND_DEVICE_IN_HEADSET_MIC,
    SND_DEVICE_IN_HANDSET_MIC_AEC,
    SND_DEVICE_IN_SPEAKER_MIC_AEC,
    SND_DEVICE_IN_HEADSET_MIC_AEC,
    SND_DEVICE_IN_VOICE_SPEAKER_MIC,
    SND_DEVICE_IN_VOICE_HEADSET_MIC,
    SND_DEVICE_IN_HDMI_MIC,
    SND_DEVICE_IN_BT_SCO_MIC,
    SND_DEVICE_IN_CAMCORDER_MIC,
    SND_DEVICE_IN_VOICE_DMIC_EF,
    SND_DEVICE_IN_VOICE_DMIC_BS,
    SND_DEVICE_IN_VOICE_DMIC_EF_TMUS,
    SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF,
    SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS,
    SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC,
    SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC,
    SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC,
    SND_DEVICE_IN_VOICE_REC_MIC,
    SND_DEVICE_IN_VOICE_REC_DMIC_EF,
    SND_DEVICE_IN_VOICE_REC_DMIC_BS,
    SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE,
    SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE,
    SND_DEVICE_IN_END,

    SND_DEVICE_MAX = SND_DEVICE_IN_END,


} snd_device_t;
#define MAX_SUPPORTED_CHANNEL_MASKS 2
#define DEFAULT_HDMI_OUT_CHANNELS   2


typedef int snd_device_t;


/* These are the supported use cases by the hardware.
/* These are the supported use cases by the hardware.
 * Each usecase is mapped to a specific PCM device.
 * Each usecase is mapped to a specific PCM device.
@@ -112,22 +53,18 @@ typedef enum {
    USECASE_AUDIO_PLAYBACK_DEEP_BUFFER = 0,
    USECASE_AUDIO_PLAYBACK_DEEP_BUFFER = 0,
    USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
    USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
    USECASE_AUDIO_PLAYBACK_MULTI_CH,
    USECASE_AUDIO_PLAYBACK_MULTI_CH,
    USECASE_AUDIO_PLAYBACK_OFFLOAD,


    /* Capture usecases */
    /* Capture usecases */
    USECASE_AUDIO_RECORD,
    USECASE_AUDIO_RECORD,
    USECASE_AUDIO_RECORD_LOW_LATENCY,
    USECASE_AUDIO_RECORD_LOW_LATENCY,


    USECASE_VOICE_CALL,
    USECASE_VOICE_CALL,

    AUDIO_USECASE_MAX
    AUDIO_USECASE_MAX
} audio_usecase_t;
} audio_usecase_t;


#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))


#define SOUND_CARD 0

#define DEFAULT_OUTPUT_SAMPLING_RATE 48000

/*
/*
 * tinyAlsa library interprets period size as number of frames
 * tinyAlsa library interprets period size as number of frames
 * one frame = channel_count * sizeof (pcm sample)
 * one frame = channel_count * sizeof (pcm sample)
@@ -136,49 +73,60 @@ typedef enum {
 * We should take care of returning proper size when AudioFlinger queries for
 * We should take care of returning proper size when AudioFlinger queries for
 * the buffer size of an input/output stream
 * the buffer size of an input/output stream
 */
 */
#ifdef MSM8974
#define DEEP_BUFFER_OUTPUT_PERIOD_SIZE 1024
#else
#define DEEP_BUFFER_OUTPUT_PERIOD_SIZE 960
#endif
#define DEEP_BUFFER_OUTPUT_PERIOD_COUNT 8


#ifdef MSM8974
enum {
#define LOW_LATENCY_OUTPUT_PERIOD_SIZE 256
    OFFLOAD_CMD_EXIT,               /* exit compress offload thread loop*/
#else
    OFFLOAD_CMD_DRAIN,              /* send a full drain request to DSP */
#define LOW_LATENCY_OUTPUT_PERIOD_SIZE 240
    OFFLOAD_CMD_PARTIAL_DRAIN,      /* send a partial drain request to DSP */
#endif
    OFFLOAD_CMD_WAIT_FOR_BUFFER,    /* wait for buffer released by DSP */
#define LOW_LATENCY_OUTPUT_PERIOD_COUNT 2
};

#define HDMI_MULTI_PERIOD_SIZE  336
#define HDMI_MULTI_PERIOD_COUNT 8
#define HDMI_MULTI_DEFAULT_CHANNEL_COUNT 6
#define HDMI_MULTI_PERIOD_BYTES (HDMI_MULTI_PERIOD_SIZE * HDMI_MULTI_DEFAULT_CHANNEL_COUNT * 2)


#ifdef MSM8974
enum {
#define AUDIO_CAPTURE_PERIOD_SIZE 512
    OFFLOAD_STATE_IDLE,
#define AUDIO_CAPTURE_PERIOD_COUNT 16
    OFFLOAD_STATE_PLAYING,
#else
    OFFLOAD_STATE_PAUSED,
#define AUDIO_CAPTURE_PERIOD_SIZE 320
};
#define AUDIO_CAPTURE_PERIOD_COUNT 2
#endif


#define MAX_SUPPORTED_CHANNEL_MASKS 2
struct offload_cmd {
    struct listnode node;
    int cmd;
    int data[];
};


struct stream_out {
struct stream_out {
    struct audio_stream_out stream;
    struct audio_stream_out stream;
    pthread_mutex_t lock; /* see note below on mutex acquisition order */
    pthread_mutex_t lock; /* see note below on mutex acquisition order */
    pthread_cond_t  cond;
    struct pcm_config config;
    struct pcm_config config;
    struct compr_config compr_config;
    struct pcm *pcm;
    struct pcm *pcm;
    struct compress *compr;
    int standby;
    int standby;
    int pcm_device_id;
    int pcm_device_id;
    unsigned int sample_rate;
    audio_channel_mask_t channel_mask;
    audio_channel_mask_t channel_mask;
    audio_format_t format;
    audio_devices_t devices;
    audio_devices_t devices;
    audio_output_flags_t flags;
    audio_output_flags_t flags;
    audio_usecase_t usecase;
    audio_usecase_t usecase;
    /* Array of supported channel mask configurations. +1 so that the last entry is always 0 */
    /* 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];
    audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];
    bool muted;
    bool muted;
    uint64_t written; /* total frames written, not cleared when entering standby */
    audio_io_handle_t handle;

    int non_blocking;
    int playback_started;
    int offload_state;
    pthread_cond_t offload_cond;
    pthread_t offload_thread;
    struct listnode offload_cmd_list;
    bool offload_thread_blocked;

    stream_callback_t offload_callback;
    void *offload_cookie;
    struct compr_gapless_mdata gapless_mdata;
    int send_new_metadata;


    struct audio_device *dev;
    struct audio_device *dev;
};
};
@@ -220,20 +168,6 @@ struct audio_usecase {
    union stream_ptr stream;
    union stream_ptr stream;
};
};


typedef void (*acdb_deallocate_t)();
typedef int  (*acdb_init_t)();
typedef void (*acdb_send_audio_cal_t)(int, int);
typedef void (*acdb_send_voice_cal_t)(int, int);

typedef int (*csd_client_init_t)();
typedef int (*csd_client_deinit_t)();
typedef int (*csd_disable_device_t)();
typedef int (*csd_enable_device_t)(int, int, uint32_t);
typedef int (*csd_volume_t)(int);
typedef int (*csd_mic_mute_t)(int);
typedef int (*csd_start_voice_t)();
typedef int (*csd_stop_voice_t)();

struct audio_device {
struct audio_device {
    struct audio_hw_device device;
    struct audio_hw_device device;
    pthread_mutex_t lock; /* see note below on mutex acquisition order */
    pthread_mutex_t lock; /* see note below on mutex acquisition order */
@@ -250,35 +184,18 @@ struct audio_device {
    bool screen_off;
    bool screen_off;
    struct pcm *voice_call_rx;
    struct pcm *voice_call_rx;
    struct pcm *voice_call_tx;
    struct pcm *voice_call_tx;
    int snd_dev_ref_cnt[SND_DEVICE_MAX];
    int *snd_dev_ref_cnt;
    struct listnode usecase_list;
    struct listnode usecase_list;
    struct audio_route *audio_route;
    struct audio_route *audio_route;
    int acdb_settings;
    int acdb_settings;
    bool speaker_lr_swap;
    bool speaker_lr_swap;
    unsigned int cur_hdmi_channels;


    bool mic_type_analog;
    void *platform;
    bool fluence_in_spkr_mode;
    bool fluence_in_voice_call;
    bool fluence_in_voice_rec;
    int  dualmic_config;


    /* Audio calibration related functions */
    void *visualizer_lib;
    void *acdb_handle;
    int (*visualizer_start_output)(audio_io_handle_t);
    acdb_init_t acdb_init;
    int (*visualizer_stop_output)(audio_io_handle_t);
    acdb_deallocate_t acdb_deallocate;
    acdb_send_audio_cal_t acdb_send_audio_cal;
    acdb_send_voice_cal_t acdb_send_voice_cal;

    /* CSD Client related functions for voice call */
    void *csd_client;
    csd_client_init_t csd_client_init;
    csd_client_deinit_t csd_client_deinit;
    csd_disable_device_t csd_disable_device;
    csd_enable_device_t csd_enable_device;
    csd_volume_t csd_volume;
    csd_mic_mute_t csd_mic_mute;
    csd_start_voice_t csd_start_voice;
    csd_stop_voice_t csd_stop_voice;
};
};


/*
/*
@@ -286,51 +203,4 @@ struct audio_device {
 * stream_in or stream_out mutex first, followed by the audio_device mutex.
 * stream_in or stream_out mutex first, followed by the audio_device mutex.
 */
 */


struct pcm_config pcm_config_deep_buffer = {
#endif // QCOM_AUDIO_HW_H
    .channels = 2,
    .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
    .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE,
    .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT,
    .format = PCM_FORMAT_S16_LE,
    .start_threshold = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
    .stop_threshold = INT_MAX,
    .avail_min = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
};

struct pcm_config pcm_config_low_latency = {
    .channels = 2,
    .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_hdmi_multi = {
    .channels = HDMI_MULTI_DEFAULT_CHANNEL_COUNT, /* changed when the stream is opened */
    .rate = DEFAULT_OUTPUT_SAMPLING_RATE, /* changed when the stream is opened */
    .period_size = HDMI_MULTI_PERIOD_SIZE,
    .period_count = HDMI_MULTI_PERIOD_COUNT,
    .format = PCM_FORMAT_S16_LE,
    .start_threshold = 0,
    .stop_threshold = INT_MAX,
    .avail_min = 0,
};

struct pcm_config pcm_config_audio_capture = {
    .channels = 2,
    .period_size = AUDIO_CAPTURE_PERIOD_SIZE,
    .period_count = AUDIO_CAPTURE_PERIOD_COUNT,
    .format = PCM_FORMAT_S16_LE,
};

struct pcm_config pcm_config_voice_call = {
    .channels = 1,
    .rate = 8000,
    .period_size = 160,
    .period_count = 2,
    .format = PCM_FORMAT_S16_LE,
};

hal/edid.c

deleted100644 → 0
+0 −93
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2013 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_primary"

#include <stdlib.h>
#include <stdio.h>

#include <cutils/log.h>

/*
 * This is the sysfs path for the HDMI audio data block
 */
#define AUDIO_DATA_BLOCK_PATH "/sys/class/graphics/fb1/audio_data_block"

/*
 * This file will have a maximum of 38 bytes:
 *
 * 4 bytes: number of audio blocks
 * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
 * Maximum 10 * 3 bytes: SAD blocks
 */
#define MAX_SAD_BLOCKS		10
#define SAD_BLOCK_SIZE		3

/* EDID format ID for LPCM audio */
#define EDID_FORMAT_LPCM	1

struct audio_block_header
{
    int reserved;
    int length;
};

int edid_get_max_channels(void)
{
    FILE *file;
    struct audio_block_header header;
    char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
    char *sad = block;
    int num_audio_blocks;
    int channel_count;
    int max_channels = 0;
    int i;

    file = fopen(AUDIO_DATA_BLOCK_PATH, "rb");
    if (file == NULL) {
        ALOGE("Unable to open '%s'", AUDIO_DATA_BLOCK_PATH);
        return 0;
    }

    /* Read audio block header */
    fread(&header, 1, sizeof(header), file);

    /* Read SAD blocks, clamping the maximum size for safety */
    if (header.length > (int)sizeof(block))
        header.length = (int)sizeof(block);
    fread(&block, header.length, 1, file);

    fclose(file);

    /* Calculate the number of SAD blocks */
    num_audio_blocks = header.length / SAD_BLOCK_SIZE;

    for (i = 0; i < num_audio_blocks; i++) {
        /* Only consider LPCM blocks */
        if ((sad[0] >> 3) != EDID_FORMAT_LPCM)
            continue;

        channel_count = (sad[0] & 0x7) + 1;
        if (channel_count > max_channels)
            max_channels = channel_count;

        /* Advance to next block */
        sad += 3;
    }

    return max_channels;
}
Loading