summaryrefslogtreecommitdiff
authorShuai Li <shuai.li@amlogic.com>2016-10-21 10:56:58 (GMT)
committer Shuai Li <shuai.li@amlogic.com>2016-10-24 10:32:46 (GMT)
commit56f838805e84501d5c07b1f92ef41d0db64bbde2 (patch)
tree34e6de5c002d2addf4982aafc4b8f290f935ae73
parent2a4846154c6c9a6e5303839444721d6c72568125 (diff)
downloadaudio-56f838805e84501d5c07b1f92ef41d0db64bbde2.zip
audio-56f838805e84501d5c07b1f92ef41d0db64bbde2.tar.gz
audio-56f838805e84501d5c07b1f92ef41d0db64bbde2.tar.bz2
modify to fit new audio policy frameswork
Change-Id: I18e8f0eb646c229e0b58976539a099f1f3ec9307
Diffstat
-rw-r--r--Android.mk49
-rw-r--r--audio_hw.c1053
-rw-r--r--audio_hw.h132
-rw-r--r--audio_hw_utils.c32
-rw-r--r--audio_hw_utils.h2
-rw-r--r--audio_hwsync.c4
-rw-r--r--spdifenc_wrap.cpp8
-rw-r--r--spdifenc_wrap.h16
8 files changed, 968 insertions, 328 deletions
diff --git a/Android.mk b/Android.mk
index 3293362..1c36d8f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -28,7 +28,10 @@ ifeq ($(strip $(BOARD_ALSA_AUDIO)),tiny)
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := \
audio_hw.c \
- libTVaudio/audio/audio_effect_control.c
+ libTVaudio/audio/audio_effect_control.c \
+ audio_hw_utils.c \
+ audio_hwsync.c \
+ //spdifenc_wrap.cpp
LOCAL_C_INCLUDES += \
external/tinyalsa/include \
system/media/audio_utils/include \
@@ -38,12 +41,12 @@ ifeq ($(strip $(BOARD_ALSA_AUDIO)),tiny)
LOCAL_SHARED_LIBRARIES := \
liblog libcutils libtinyalsa \
- libaudioutils libdl libaudioroute libutils
+ libaudioutils libdl libaudioroute libutils \
+ libaudiospdif
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
#build for USB audio
-#BOARD_USE_USB_AUDIO := 1
ifeq ($(strip $(BOARD_USE_USB_AUDIO)),true)
include $(CLEAR_VARS)
@@ -61,6 +64,8 @@ ifeq ($(strip $(BOARD_ALSA_AUDIO)),tiny)
include $(BUILD_SHARED_LIBRARY)
endif
#build for hdmi audio HAL
+ifeq ($(strip $(BOARD_USE_HDMI_HAL)),true)
+ #ifneq ($(strip $(BOARD_USE_HDMI_HAL)),true)
include $(CLEAR_VARS)
LOCAL_MODULE := audio.hdmi.amlogic
@@ -89,42 +94,6 @@ LOCAL_SRC_FILES += audio_hw_utils.c
LOCAL_SRC_FILES += audio_hwsync.c
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
-
-#########################################################
-
-
-
-#########################################################
-# Audio Policy Manager
-ifeq ($(USE_CUSTOM_AUDIO_POLICY),1)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- DLGAudioPolicyManager.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- liblog \
- libutils \
- libmedia \
- libbinder \
- libaudiopolicymanagerdefault \
- libutils
-
-LOCAL_C_INCLUDES := \
- external/tinyalsa/include \
- $(TOPDIR)frameworks/av/services/audiopolicy \
- $(TOPDIR)frameworks/av/services/audiopolicy/managerdefault \
- $(TOPDIR)frameworks/av/services/audiopolicy/engine/interface \
- $(TOPDIR)frameworks/av/services/audiopolicy/common/managerdefinitions/include \
- $(TOPDIR)frameworks/av/services/audiopolicy/common/include
-
-
-LOCAL_MODULE := libaudiopolicymanager
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-endif # USE_CUSTOM_AUDIO_POLICY
-
+ endif
endif # BOARD_ALSA_AUDIO
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/audio_hw.c b/audio_hw.c
index 2103ad4..de44ad0 100644
--- a/audio_hw.c
+++ b/audio_hw.c
@@ -15,9 +15,9 @@
*/
#define LOG_TAG "audio_hw_primary"
-#define LOG_NDEBUG 0
-//#define LOG_NDEBUG_FUNCTION
-#ifdef LOG_NDEBUG_FUNCTION
+//#define LOG_NALOGV 0
+//#define LOG_NALOGV_FUNCTION
+#ifdef LOG_NALOGV_FUNCTION
#define LOGFUNC(...) ((void)0)
#else
#define LOGFUNC(...) (ALOGD(__VA_ARGS__))
@@ -41,26 +41,31 @@
#include <hardware/audio.h>
#include <sound/asound.h>
#include <tinyalsa/asoundlib.h>
-#include <audio_utils/resampler.h>
#include <audio_utils/echo_reference.h>
#include <hardware/audio_effect.h>
#include <audio_effects/effect_aec.h>
#include <audio_route/audio_route.h>
#include "libTVaudio/audio/audio_effect_control.h"
-
-
+#include "audio_hw.h"
+#include "audio_hw_utils.h"
+#include "spdifenc_wrap.h"
+//extern int spdifenc_write(const void *buffer, size_t numBytes);
+//extern uint64_t spdifenc_get_total();
+extern void aml_audio_hwsync_clear_status(struct aml_stream_out *out);
+extern int aml_audio_hwsync_find_frame(struct aml_stream_out *out,
+ const void *in_buffer, size_t in_bytes, uint64_t *cur_pts, int *outsize);
/* ALSA cards for AML */
#define CARD_AMLOGIC_BOARD 0
-#define CARD_AMLOGIC_USB 1
-#define CARD_AMLOGIC_DEFAULT CARD_AMLOGIC_BOARD
/* ALSA ports for AML */
-#define PORT_MM 0
+#define PORT_I2S 0
+#define PORT_SPDIF 1
+#define PORT_PCM 2
/* number of frames per period */
#define DEFAULT_PERIOD_SIZE 1024
#define DEFAULT_CAPTURE_PERIOD_SIZE 1024
-static unsigned PERIOD_SIZE = DEFAULT_PERIOD_SIZE;
+//static unsigned PERIOD_SIZE = DEFAULT_PERIOD_SIZE;
static unsigned CAPTURE_PERIOD_SIZE = DEFAULT_CAPTURE_PERIOD_SIZE;
/* number of periods for low power playback */
#define PLAYBACK_PERIOD_COUNT 4
@@ -75,7 +80,7 @@ static unsigned CAPTURE_PERIOD_SIZE = DEFAULT_CAPTURE_PERIOD_SIZE;
#define NSEC_PER_SECOND 1000000000ULL
-static unsigned int DEFAULT_OUT_SAMPLING_RATE = 48000;
+//static unsigned int DEFAULT_OUT_SAMPLING_RATE = 48000;
/* sampling rate when using MM low power port */
#define MM_LOW_POWER_SAMPLING_RATE 44100
@@ -93,8 +98,6 @@ static unsigned int DEFAULT_OUT_SAMPLING_RATE = 48000;
#define APTS_DISCONTINUE_THRESHOLD_MIN (90000/1000*100)
#define APTS_DISCONTINUE_THRESHOLD_MAX (5*90000)
-#define MAX_STREAM_NUM 5
-
static const struct pcm_config pcm_config_out = {
.channels = 2,
.rate = MM_FULL_POWER_SAMPLING_RATE,
@@ -103,6 +106,14 @@ static const struct pcm_config pcm_config_out = {
.format = PCM_FORMAT_S16_LE,
};
+static const struct pcm_config pcm_config_out_direct = {
+ .channels = 2,
+ .rate = MM_FULL_POWER_SAMPLING_RATE,
+ .period_size = DEFAULT_PERIOD_SIZE,
+ .period_count = PLAYBACK_PERIOD_COUNT,
+ .format = PCM_FORMAT_S16_LE,
+};
+
static const struct pcm_config pcm_config_in = {
.channels = 2,
.rate = MM_FULL_POWER_SAMPLING_RATE,
@@ -118,103 +129,11 @@ static const struct pcm_config pcm_config_bt = {
.period_count = PLAYBACK_PERIOD_COUNT,
.format = PCM_FORMAT_S16_LE,
};
-#define AML_HAL_MIXER_BUF_SIZE 64*1024
-struct aml_hal_mixer {
- unsigned char start_buf[AML_HAL_MIXER_BUF_SIZE];
- unsigned int wp;
- unsigned int rp;
- unsigned int buf_size;
- unsigned char need_cache_flag;//flag to check if need cache some data before write to mix
- pthread_mutex_t lock;
-};
-struct aml_audio_device {
- struct audio_hw_device hw_device;
-
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
- pthread_mutex_t pcm_write_lock;
- int mode;
- audio_devices_t in_device;
- audio_devices_t out_device;
- int in_call;
- struct aml_stream_in *active_input;
- struct aml_stream_out *active_output[MAX_STREAM_NUM];
- unsigned char active_output_count;
- bool mic_mute;
- unsigned int card;
- struct audio_route *ar;
- struct echo_reference_itfe *echo_reference;
- bool low_power;
- struct aml_stream_out *hwsync_output;
- struct aml_hal_mixer hal_mixer;
- struct pcm *pcm;
-};
#define HW_SYNC_STATE_HEADER 0
#define HW_SYNC_STATE_BODY 1
#define HW_SYNC_STATE_RESYNC 2
-struct aml_stream_out {
- struct audio_stream_out stream;
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
- struct pcm_config config;
- struct pcm *pcm;
- struct resampler_itfe *resampler;
- char *buffer;
- size_t buffer_frames;
- bool standby;
- struct echo_reference_itfe *echo_reference;
- struct aml_audio_device *dev;
- int write_threshold;
- bool low_power;
- uint64_t frame_write_sum;
- uint64_t last_frames_postion;
- uint8_t hw_sync_header[16];
- int hw_sync_header_cnt;
- int hw_sync_state;
- int hw_sync_body_cnt;
- uint8_t body_align[64];
- uint8_t body_align_cnt;
- int32_t *tmp_buffer_8ch;
- int is_tv_platform;
- void *audioeffect_tmp_buffer;
- int has_SRS_lib;
- int has_EQ_lib;
- unsigned char pause_status;
- bool hw_sync_mode;
- bool first_apts_flag;//flag to indicate set first apts
- uint64_t first_apts;
- uint64_t last_apts_from_header;
- int has_aml_IIR_lib;
- float volume_l;
- float volume_r;
-};
-#define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */
-struct aml_stream_in {
- struct audio_stream_in stream;
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
- struct pcm_config config;
- struct pcm *pcm;
- int device;
- struct resampler_itfe *resampler;
- struct resampler_buffer_provider buf_provider;
- int16_t *buffer;
- size_t frames_in;
- unsigned int requested_rate;
- bool standby;
- int source;
- struct echo_reference_itfe *echo_reference;
- bool need_echo_reference;
- effect_handle_t preprocessors[MAX_PREPROCESSORS];
- int num_preprocessors;
- int16_t *proc_buf;
- size_t proc_buf_size;
- size_t proc_frames_in;
- int16_t *ref_buf;
- size_t ref_buf_size;
- size_t ref_frames_in;
- int read_status;
- struct aml_audio_device *dev;
-};
static void select_output_device(struct aml_audio_device *adev);
static void select_input_device(struct aml_audio_device *adev);
static void select_devices(struct aml_audio_device *adev);
@@ -241,7 +160,7 @@ static int aml_hal_mixer_init(struct aml_hal_mixer *mixer)
pthread_mutex_unlock(&mixer->lock);
return 0;
}
-static int aml_hal_mixer_get_space(struct aml_hal_mixer *mixer)
+static uint aml_hal_mixer_get_space(struct aml_hal_mixer *mixer)
{
unsigned space;
if (mixer->wp >= mixer->rp) {
@@ -266,7 +185,7 @@ static int aml_hal_mixer_get_content(struct aml_hal_mixer *mixer)
}
//we assue the cached size is always smaller then buffer size
//need called by device mutux locked
-static int aml_hal_mixer_write(struct aml_hal_mixer *mixer, void *w_buf, int size)
+static int aml_hal_mixer_write(struct aml_hal_mixer *mixer, const void *w_buf, uint size)
{
unsigned space;
unsigned write_size = size;
@@ -297,7 +216,7 @@ static int aml_hal_mixer_write(struct aml_hal_mixer *mixer, void *w_buf, int siz
return size;
}
//need called by device mutux locked
-static int aml_hal_mixer_read(struct aml_hal_mixer *mixer, void *r_buf, int size)
+static int aml_hal_mixer_read(struct aml_hal_mixer *mixer, void *r_buf, uint size)
{
unsigned cached_size;
unsigned read_size = size;
@@ -326,85 +245,7 @@ static int aml_hal_mixer_read(struct aml_hal_mixer *mixer, void *r_buf, int size
return size;
}
// aml audio hal mixer code end
-
-static int getprop_bool(const char * path)
-{
- char buf[PROPERTY_VALUE_MAX];
- int ret = -1;
-
- ret = property_get(path, buf, NULL);
- if (ret > 0) {
- if (strcasecmp(buf, "true") == 0 || strcmp(buf, "1") == 0) {
- return 1;
- }
- }
- return 0;
-}
-static int get_sysfs_int(const char * path)
-{
- int val = 0;
- int fd = open(path, O_RDONLY);
- if (fd >= 0) {
- char bcmd[16];
- read(fd, bcmd, sizeof(bcmd));
- val = strtol(bcmd, NULL, 10);
- close(fd);
- } else {
- LOGFUNC("[%s]open %s node failed! return 0\n", path, __FUNCTION__);
- }
- return val;
-}
-static int get_sysfs_int16(const char *path, unsigned *value)
-{
- int fd;
- char valstr[64];
- unsigned val = 0;
- fd = open(path, O_RDONLY);
- if (fd >= 0) {
- memset(valstr, 0, 64);
- read(fd, valstr, 64 - 1);
- valstr[strlen(valstr)] = '\0';
- close(fd);
- } else {
- ALOGE("unable to open file %s\n", path);
- return -1;
- }
- if (sscanf(valstr, "0x%lx", &val) < 1) {
- ALOGE("unable to get pts from: %s", valstr);
- return -1;
- }
- *value = val;
- return 0;
-}
-static int sysfs_set_sysfs_str(const char *path, const char *val)
-{
- int fd;
- int bytes;
- fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
- if (fd >= 0) {
- bytes = write(fd, val, strlen(val));
- close(fd);
- return 0;
- } else {
- ALOGE("unable to open file %s,err: %s", path, strerror(errno));
- }
- return -1;
-}
-
-static void
-set_codec_type(int type)
-{
- char buf[16];
- int fd = open("/sys/class/audiodsp/digital_codec", O_WRONLY);
-
- if (fd >= 0) {
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "%d", type);
-
- write(fd, buf, sizeof(buf));
- close(fd);
- }
-}
+#if 0
static inline bool hwsync_header_valid(uint8_t *header)
{
return (header[0] == 0x55) &&
@@ -432,6 +273,7 @@ static inline uint32_t hwsync_header_get_size(uint8_t *header)
(((uint32_t)header[6]) << 8) |
((uint32_t)header[7]);
}
+#endif
static void select_devices(struct aml_audio_device *adev)
{
@@ -476,39 +318,13 @@ static void select_devices(struct aml_audio_device *adev)
audio_route_update_mixer(adev->ar);
}
-#if 0
-static void force_all_standby(struct aml_audio_device *adev)
-{
- struct aml_stream_in *in;
- struct aml_stream_out *out;
- LOGFUNC("%s(%p)", __FUNCTION__, adev);
- int i = 0;
- for (i = 0; i < MAX_STREAM_NUM; i++) {
- out = adev->active_output[i];
-
- }
- if (adev->active_output) {
- out = adev->active_output;
- pthread_mutex_lock(&out->lock);
- do_output_standby(out);
- pthread_mutex_unlock(&out->lock);
- }
-
- if (adev->active_input) {
- in = adev->active_input;
- pthread_mutex_lock(&in->lock);
- do_input_standby(in);
- pthread_mutex_unlock(&in->lock);
- }
-}
-#endif
static void select_mode(struct aml_audio_device *adev)
{
LOGFUNC("%s(out_device=%#x)", __FUNCTION__, adev->out_device);
LOGFUNC("%s(in_device=%#x)", __FUNCTION__, adev->in_device);
return;
- //force_all_standby(adev);
+
/* force earpiece route for in call state if speaker is the
only currently selected route. This prevents having to tear
down the modem PCMs to change route from speaker to earpiece
@@ -639,8 +455,8 @@ OUT:
static int start_output_stream(struct aml_stream_out *out)
{
struct aml_audio_device *adev = out->dev;
- unsigned int card = CARD_AMLOGIC_DEFAULT;
- unsigned int port = PORT_MM;
+ unsigned int card = CARD_AMLOGIC_BOARD;
+ unsigned int port = PORT_I2S;
int ret;
int i = 0;
struct aml_stream_out *out_removed = NULL;
@@ -668,11 +484,12 @@ static int start_output_stream(struct aml_stream_out *out)
}
card = get_aml_card();
if (adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
- port = get_pcm_bt_port();
+ port = PORT_PCM;
out->config = pcm_config_bt;
- } else {
- port = PORT_MM;
+ } else if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT){
+ port = PORT_SPDIF;
}
+
LOGFUNC("*%s, open card(%d) port(%d)", __FUNCTION__, card, port);
/* default to low power: will be corrected in out_write if necessary before first write to
@@ -752,6 +569,103 @@ static int start_output_stream(struct aml_stream_out *out)
return 0;
}
+/* dircet stream mainly map to audio HDMI port */
+static int start_output_stream_direct(struct aml_stream_out *out)
+{
+ struct aml_audio_device *adev = out->dev;
+ unsigned int card = CARD_AMLOGIC_BOARD;
+ unsigned int port = PORT_SPDIF;
+ int ret = 0;
+
+ int codec_type = get_codec_type(out->hal_format);
+ if (codec_type == AUDIO_FORMAT_PCM && out->config.rate > 48000 && (out->flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
+ ALOGI("start output stream for high sample rate pcm for direct mode\n");
+ codec_type = TYPE_PCM_HIGH_SR;
+ }
+ if (codec_type == AUDIO_FORMAT_PCM && out->config.channels >= 6 && (out->flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
+ ALOGI("start output stream for multi-channel pcm for direct mode\n");
+ codec_type = TYPE_MULTI_PCM;
+ }
+
+ card = get_aml_card();
+ ALOGI("hdmi sound card id %d,device id %d \n", card, port);
+
+ if (out->config.channels == 6) {
+ ALOGI("round 6ch to 8 ch output \n");
+ /* our hw only support 8 channel configure,so when 5.1,hw mask the last two channels*/
+ sysfs_set_sysfs_str("/sys/class/amhdmitx/amhdmitx0/aud_output_chs", "6:7");
+ out->config.channels = 8;
+ }
+ /*
+ * 8 channel audio only support 32 byte mode,so need convert them to
+ * PCM_FORMAT_S32_LE
+ */
+ if (out->config.channels == 8) {
+ port = PORT_I2S;
+ out->config.format = PCM_FORMAT_S32_LE;
+ adev->out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ ALOGI("[%s %d]8CH format output: set port/0 adev->out_device/%d\n",
+ __FUNCTION__, __LINE__, AUDIO_DEVICE_OUT_SPEAKER);
+ }
+ if (getprop_bool("media.libplayer.wfd")) {
+ out->config.period_size = PERIOD_SIZE;
+ }
+ switch (out->hal_format) {
+ case AUDIO_FORMAT_E_AC3:
+ out->config.period_size = PERIOD_SIZE * 2;
+ out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 2;
+ out->config.start_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 2;
+ break;
+ case AUDIO_FORMAT_DTS_HD:
+ case AUDIO_FORMAT_TRUEHD:
+ out->config.period_size = PERIOD_SIZE * 4 * 2;
+ out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 4 * 2;
+ out->config.start_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE * 4 * 2;
+ break;
+ case AUDIO_FORMAT_PCM:
+ default:
+ out->config.period_size = PERIOD_SIZE;
+ out->write_threshold = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE;
+ out->config.start_threshold = PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
+ }
+ out->config.avail_min = 0;
+ set_codec_type(codec_type);
+
+ if (out->config.channels == 6) {
+ ALOGI("round 6ch to 8 ch output \n");
+ /* our hw only support 8 channel configure,so when 5.1,hw mask the last two channels*/
+ sysfs_set_sysfs_str("/sys/class/amhdmitx/amhdmitx0/aud_output_chs", "6:7");
+ out->config.channels = 8;
+ }
+ ALOGI("ALSA open configs: channels=%d, format=%d, period_count=%d, period_size=%d,,rate=%d",
+ out->config.channels, out->config.format, out->config.period_count,
+ out->config.period_size, out->config.rate);
+
+ if (out->pcm == NULL) {
+ out->pcm = pcm_open(card, port, PCM_OUT, &out->config);
+ if (!pcm_is_ready(out->pcm)) {
+ ALOGE("cannot open pcm_out driver: %s", pcm_get_error(out->pcm));
+ pcm_close(out->pcm);
+ return -EINVAL;
+ }
+ } else {
+ ALOGE("stream %p share the pcm %p\n", out, out->pcm);
+ }
+
+ if (codec_type_is_raw_data(codec_type) && !(out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
+ spdifenc_init(out->pcm);
+ out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
+ }
+ out->codec_type = codec_type;
+ out->bytes_write_total = 0;
+
+ if (out->hw_sync_mode == 1) {
+ LOGFUNC("start_output_stream with hw sync enable %p\n", out);
+ }
+
+ return 0;
+}
+
static int check_input_parameters(uint32_t sample_rate, audio_format_t format, int channel_count)
{
LOGFUNC("%s(sample_rate=%d, format=%d, channel_count=%d)", __FUNCTION__, sample_rate, format, channel_count);
@@ -894,9 +808,10 @@ static int get_playback_delay(struct aml_stream_out *out,
static uint32_t out_get_sample_rate(const struct audio_stream *stream)
{
- struct aml_stream_out *out = (struct aml_stream_out *)stream;
- //LOGFUNC("%s(%p)", __FUNCTION__, stream);
- return out->config.rate;
+ const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
+ unsigned int rate = out->hal_rate;
+ //ALOGV("out_get_sample_rate() = %d", rate);
+ return rate;
}
static int out_set_sample_rate(struct audio_stream *stream __unused, uint32_t rate __unused)
@@ -915,20 +830,64 @@ static size_t out_get_buffer_size(const struct audio_stream *stream)
* be a multiple of 16 frames
*/
size_t size = out->config.period_size;
+ switch (out->hal_format) {
+ case AUDIO_FORMAT_AC3:
+ case AUDIO_FORMAT_DTS:
+ if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
+ size = 4 * PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
+ } else {
+ size = PLAYBACK_PERIOD_COUNT * PERIOD_SIZE / 2;
+ }
+ break;
+ case AUDIO_FORMAT_E_AC3:
+ if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
+ size = 16 * PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
+ } else {
+ size = PERIOD_SIZE; //2*PLAYBACK_PERIOD_COUNT*PERIOD_SIZE;
+ }
+ break;
+ case AUDIO_FORMAT_DTS_HD:
+ case AUDIO_FORMAT_TRUEHD:
+ if (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO) {
+ size = 16 * PERIOD_SIZE * PLAYBACK_PERIOD_COUNT;
+ } else {
+ size = 4 * PLAYBACK_PERIOD_COUNT * PERIOD_SIZE;
+ }
+ break;
+ case AUDIO_FORMAT_PCM:
+ default:
+ size = PERIOD_SIZE;
+ }
size = ((size + 15) / 16) * 16;
return size * audio_stream_out_frame_size((struct audio_stream_out *)stream);
}
static audio_channel_mask_t out_get_channels(const struct audio_stream *stream __unused)
{
+ //const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
+
return AUDIO_CHANNEL_OUT_STEREO;
}
+static audio_channel_mask_t out_get_channels_direct(const struct audio_stream *stream)
+{
+ const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
+
+ return out->hal_channel_mask;
+}
+
static audio_format_t out_get_format(const struct audio_stream *stream __unused)
{
return AUDIO_FORMAT_PCM_16_BIT;
}
+static audio_format_t out_get_format_direct(const struct audio_stream *stream)
+{
+ const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
+
+ return out->hal_format;
+}
+
static int out_set_format(struct audio_stream *stream __unused, audio_format_t format __unused)
{
return 0;
@@ -1018,13 +977,45 @@ static int out_standby(struct audio_stream *stream)
return status;
}
+static int out_standby_direct(struct audio_stream *stream)
+{
+ struct aml_stream_out *out = (struct aml_stream_out *) stream;
+ int status = 0;
+
+ ALOGI("%s(%p),out %p", __FUNCTION__, stream, out);
+
+ pthread_mutex_lock(&out->dev->lock);
+ pthread_mutex_lock(&out->lock);
+ if (!out->standby) {
+ if (out->buffer) {
+ free(out->buffer);
+ out->buffer = NULL;
+ }
+
+ out->standby = 1;
+ pcm_close(out->pcm);
+ out->pcm = NULL;
+ }
+ set_codec_type(TYPE_PCM);
+ /* clear the hdmitx channel config to default */
+ if (out->multich == 6) {
+ sysfs_set_sysfs_str("/sys/class/amhdmitx/amhdmitx0/aud_output_chs", "0:0");
+ }
+ if (out->hal_format != AUDIO_FORMAT_DTS_HD) {
+ set_codec_type(TYPE_PCM);
+ }
+ pthread_mutex_unlock(&out->lock);
+ pthread_mutex_unlock(&out->dev->lock);
+ return status;
+}
+
static int out_dump(const struct audio_stream *stream __unused, int fd __unused)
{
LOGFUNC("%s(%p, %d)", __FUNCTION__, stream, fd);
return 0;
}
static int
-out_flush(const struct audio_stream *stream)
+out_flush(struct audio_stream_out *stream)
{
LOGFUNC("%s(%p)", __FUNCTION__, stream);
struct aml_stream_out *out = (struct aml_stream_out *) stream;
@@ -1232,7 +1223,7 @@ static uint32_t out_get_latency(const struct audio_stream_out *stream)
{
const struct aml_stream_out *out = (const struct aml_stream_out *)stream;
uint32_t whole_latency;
- uint32_t ret;
+ int ret = 0;
snd_pcm_sframes_t frames = 0;
whole_latency = (out->config.period_size * out->config.period_count * 1000) / out->config.rate;
if (!out->pcm || !pcm_is_ready(out->pcm)) {
@@ -1350,7 +1341,7 @@ static int audio_effect_process(struct audio_stream_out *stream,
return output_size;
}
-static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
+static ssize_t out_write_legacy(struct audio_stream_out *stream, const void* buffer,
size_t bytes)
{
int ret = 0;
@@ -1456,7 +1447,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
unsigned char *header;
if (out->hw_sync_state == HW_SYNC_STATE_RESYNC) {
- int i = 0;
+ uint i = 0;
uint8_t *p = (uint8_t *)buffer;
while (i < bytes) {
if (hwsync_header_valid(p)) {
@@ -1465,10 +1456,10 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
out->hw_sync_header_cnt = 0;
out->first_apts_flag = false;
bytes -= i;
- buffer += i;
+ p += i;
in_frames = bytes / frame_size;
ALOGI("in_frames = %d", in_frames);
- in_buffer = (int16_t *)buffer;
+ in_buffer = (int16_t *)p;
break;
} else {
i += 4;
@@ -1577,7 +1568,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
if (out->hw_sync_mode) {
int remain = out_frames * frame_size;
- uint8_t *p = buffer;
+ uint8_t *p = (uint8_t *)buffer;
//ALOGI(" --- out_write %d, cache cnt = %d, body = %d, hw_sync_state = %d", out_frames * frame_size, out->body_align_cnt, out->hw_sync_body_cnt, out->hw_sync_state);
@@ -1587,7 +1578,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
out->hw_sync_header[out->hw_sync_header_cnt++] = *p++;
remain--;
if (out->hw_sync_header_cnt == 16) {
- uint64_t pts;
+ int64_t pts;
if (!hwsync_header_valid(&out->hw_sync_header[0])) {
ALOGE("hwsync header out of sync! Resync.");
out->hw_sync_state = HW_SYNC_STATE_RESYNC;
@@ -1607,7 +1598,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
out->first_apts = pts;
out->frame_write_sum = 0;
out->last_apts_from_header = pts;
- sprintf(buf, "AUDIO_START:0x%lx", pts & 0xffffffff);
+ sprintf(buf, "AUDIO_START:0x%llx", pts & 0xffffffff);
ALOGI("tsync -> %s", buf);
if (sysfs_set_sysfs_str(TSYNC_EVENT, buf) == -1) {
ALOGE("set AUDIO_START failed \n");
@@ -1627,15 +1618,15 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
// here we use acutal audio frame gap,not use the differece of caculated current apts with the current frame pts,
//as there is a offset of audio latency from alsa.
// handle audio gap 0.5~5 s
- unsigned two_frame_gap = (unsigned)abs(out->last_apts_from_header - pts);
+ unsigned two_frame_gap = (unsigned)llabs(out->last_apts_from_header - pts);
if (two_frame_gap > APTS_DISCONTINUE_THRESHOLD_MIN && two_frame_gap < APTS_DISCONTINUE_THRESHOLD_MAX) {
/* if (abs(pts -apts) > APTS_DISCONTINUE_THRESHOLD_MIN && abs(pts -apts) < APTS_DISCONTINUE_THRESHOLD_MAX) { */
ALOGI("HW sync PTS discontinue, 0x%llx->0x%llx(from header) diff %d,last apts %llx(from header)",
apts, pts, two_frame_gap, out->last_apts_from_header);
//here handle the audio gap and insert zero to the alsa
- int insert_size = 0;
- int insert_size_total = 0;
- int once_write_size = 0;
+ uint insert_size = 0;
+ uint insert_size_total = 0;
+ uint once_write_size = 0;
insert_size = two_frame_gap/*abs(pts -apts) */ / 90 * 48 * 4;
insert_size = insert_size & (~63);
insert_size_total = insert_size;
@@ -1702,13 +1693,13 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
}
#endif
} else {
- unsigned long pcr = 0;
+ int pcr = 0;
if (get_sysfs_int16(TSYNC_PCRSCR, &pcr) == 0) {
- uint32_t apts_cal = apts & 0xffffffff;
+ int32_t apts_cal = apts & 0xffffffff;
if (abs(pcr - apts_cal) < SYSTIME_CORRECTION_THRESHOLD) {
// do nothing
} else {
- sprintf(buf, "0x%lx", apts_cal);
+ sprintf(buf, "0x%x", apts_cal);
ALOGI("tsync -> reset pcrscr 0x%x -> 0x%x, diff %d ms,frame pts %llx,latency pts %d", pcr, apts_cal, (int)(apts_cal - pcr) / 90, pts, latency);
int ret_val = sysfs_set_sysfs_str(TSYNC_APTS, buf);
if (ret_val == -1) {
@@ -1725,8 +1716,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
}
continue;
} else if (out->hw_sync_state == HW_SYNC_STATE_BODY) {
- int align;
- int m = (out->hw_sync_body_cnt < remain) ? out->hw_sync_body_cnt : remain;
+ uint align;
+ uint m = (out->hw_sync_body_cnt < remain) ? out->hw_sync_body_cnt : remain;
//ALOGI("m = %d", m);
@@ -1767,7 +1758,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
pthread_mutex_unlock(&adev->lock);
for (i = 0; i < 64 / 2 / 2; i++) {
- int r;
+ uint r;
r = w_buf[2 * i] * out->volume_l + mix_buf[2 * i];
w_buf[2 * i] = CLIP(r);
r = w_buf[2 * i + 1] * out->volume_r + mix_buf[2 * i + 1];
@@ -1775,7 +1766,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
}
} else {
for (i = 0; i < 64 / 2 / 2; i++) {
- int r;
+ uint r;
r = w_buf[2 * i] * out->volume_l;
w_buf[2 * i] = CLIP(r);
r = w_buf[2 * i + 1] * out->volume_r;
@@ -1926,6 +1917,478 @@ exit:
return oldBytes;
}
+static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
+ size_t bytes)
+{
+ int ret = 0;
+ struct aml_stream_out *out = (struct aml_stream_out *)stream;
+ struct aml_audio_device *adev = out->dev;
+ size_t frame_size = audio_stream_out_frame_size(stream);
+ size_t in_frames = bytes / frame_size;
+ size_t out_frames;
+ bool force_input_standby = false;
+ int16_t *in_buffer = (int16_t *)buffer;
+ struct aml_stream_in *in;
+ char output_buffer_bytes[RESAMPLER_BUFFER_SIZE + 128];
+ uint ouput_len;
+ char *data, *data_dst;
+ volatile char *data_src;
+ uint i, total_len;
+ int codec_type = 0;
+ int samesource_flag = 0;
+ uint32_t latency_frames = 0;
+ int need_mix = 0;
+ short *mix_buf = NULL;
+ unsigned char enable_dump = getprop_bool("media.audiohal.outdump");
+
+ /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
+ * on the output stream mutex - e.g. executing select_mode() while holding the hw device
+ * mutex
+ */
+ pthread_mutex_lock(&adev->lock);
+ pthread_mutex_lock(&out->lock);
+
+#if 1
+ if (enable_dump && out->hw_sync_mode == 0) {
+ FILE *fp1 = fopen("/data/tmp/i2s_audio_out.pcm", "a+");
+ if (fp1) {
+ int flen = fwrite((char *)buffer, 1, bytes, fp1);
+ fclose(fp1);
+ }
+ }
+#endif
+
+ if (out->standby) {
+ ret = start_output_stream(out);
+ if (ret != 0) {
+ pthread_mutex_unlock(&adev->lock);
+ ALOGE("start_output_stream failed");
+ goto exit;
+ }
+ out->standby = false;
+ /* a change in output device may change the microphone selection */
+ if (adev->active_input &&
+ adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
+ force_input_standby = true;
+ }
+ }
+ pthread_mutex_unlock(&adev->lock);
+#if 1
+ /* Reduce number of channels, if necessary */
+ if (popcount(out_get_channels(&stream->common)) >
+ (int)out->config.channels) {
+ unsigned int i;
+
+ /* Discard right channel */
+ for (i = 1; i < in_frames; i++) {
+ in_buffer[i] = in_buffer[i * 2];
+ }
+
+ /* The frame size is now half */
+ frame_size /= 2;
+ }
+#endif
+ /* only use resampler if required */
+ if (out->config.rate != out_get_sample_rate(&stream->common)) {
+ out_frames = out->buffer_frames;
+ out->resampler->resample_from_input(out->resampler,
+ in_buffer, &in_frames,
+ (int16_t*)out->buffer, &out_frames);
+ in_buffer = (int16_t*)out->buffer;
+ } else {
+ out_frames = in_frames;
+ }
+ if (out->echo_reference != NULL) {
+
+ struct echo_reference_buffer b;
+ b.raw = (void *)buffer;
+ b.frame_count = in_frames;
+ get_playback_delay(out, out_frames, &b);
+ out->echo_reference->write(out->echo_reference, &b);
+ }
+
+#if 1
+ if (!(adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO)) {
+ codec_type = get_sysfs_int("/sys/class/audiodsp/digital_codec");
+ samesource_flag = get_sysfs_int("/sys/class/audiodsp/audio_samesource");
+ if (samesource_flag == 0 && codec_type == 0) {
+ ALOGI("to enable same source,need reset alsa,type %d,same source flag %d \n",
+ codec_type, samesource_flag);
+ pcm_stop(out->pcm);
+ }
+ }
+#endif
+
+ struct aml_hal_mixer *mixer = &adev->hal_mixer;
+ pthread_mutex_lock(&adev->pcm_write_lock);
+ if (aml_hal_mixer_get_content(mixer) > 0) {
+ pthread_mutex_lock(&mixer->lock);
+ if (mixer->wp > mixer->rp) {
+ pcm_write(out->pcm, mixer->start_buf + mixer->rp, mixer->wp - mixer->rp);
+ } else {
+ pcm_write(out->pcm, mixer->start_buf + mixer->wp, mixer->buf_size - mixer->rp);
+ pcm_write(out->pcm, mixer->start_buf, mixer->wp);
+ }
+ mixer->rp = mixer->wp = 0;
+ pthread_mutex_unlock(&mixer->lock);
+ }
+ ret = pcm_write(out->pcm, in_buffer, out_frames * frame_size);
+ pthread_mutex_unlock(&adev->pcm_write_lock);
+ out->frame_write_sum += out_frames;
+
+exit:
+ latency_frames = out_get_latency(out) * out->config.rate / 1000;
+ if (out->frame_write_sum >= latency_frames) {
+ out->last_frames_postion = out->frame_write_sum - latency_frames;
+ } else {
+ out->last_frames_postion = out->frame_write_sum;
+ }
+ pthread_mutex_unlock(&out->lock);
+ if (ret != 0) {
+ usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
+ out_get_sample_rate(&stream->common) * 15 / 16);
+ }
+
+ if (force_input_standby) {
+ pthread_mutex_lock(&adev->lock);
+ if (adev->active_input) {
+ in = adev->active_input;
+ pthread_mutex_lock(&in->lock);
+ do_input_standby(in);
+ pthread_mutex_unlock(&in->lock);
+ }
+ pthread_mutex_unlock(&adev->lock);
+ }
+ return bytes;
+}
+
+static ssize_t out_write_direct(struct audio_stream_out *stream, const void* buffer,
+ size_t bytes)
+{
+ int ret = 0;
+ struct aml_stream_out *out = (struct aml_stream_out *) stream;
+ struct aml_audio_device *adev = out->dev;
+ size_t frame_size = audio_stream_out_frame_size(stream);
+ size_t in_frames = bytes / frame_size;
+ bool force_input_standby = false;
+ size_t out_frames = 0;
+ void *buf;
+ uint i, total_len;
+ char prop[PROPERTY_VALUE_MAX];
+ int codec_type = out->codec_type;
+ int samesource_flag = 0;
+ uint32_t latency_frames;
+ uint64_t total_frame = 0;
+ audio_hwsync_t *p_hwsync = &adev->hwsync;
+ /* acquiring hw device mutex systematically is useful if a low priority thread is waiting
+ * on the output stream mutex - e.g. executing select_mode() while holding the hw device
+ * mutex
+ */
+ out->bytes_write_total += bytes;
+ ALOGV("out %p,dev %p out_write total size %lld\n", out, adev, out->bytes_write_total);
+ pthread_mutex_lock(&adev->lock);
+ pthread_mutex_lock(&out->lock);
+ if (out->pause_status == true) {
+ pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&out->lock);
+ ALOGI("call out_write when pause status,size %d,(%p)\n", bytes, out);
+ return 0;
+ }
+ if ((out->standby) && adev->hw_sync_mode) {
+ /*
+ there are two types of raw data come to hdmi audio hal
+ 1) compressed audio data without IEC61937 wrapped
+ 2) compressed audio data with IEC61937 wrapped (typically from amlogic amadec source)
+ we use the AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO to distiguwish the two cases.
+ */
+ if ((codec_type == TYPE_AC3 || codec_type == TYPE_EAC3) && (out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
+ spdifenc_init(out->pcm);
+ out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
+ }
+ // todo: check timestamp header PTS discontinue for new sync point after seek
+ aml_audio_hwsync_clear_status(out);
+ out->spdif_enc_init_frame_write_sum = out->frame_write_sum;
+ }
+ if (out->standby) {
+ ret = start_output_stream_direct(out);
+ if (ret != 0) {
+ pthread_mutex_unlock(&adev->lock);
+ goto exit;
+ }
+ out->standby = 0;
+ /* a change in output device may change the microphone selection */
+ if (adev->active_input &&
+ adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
+ force_input_standby = true;
+ }
+ }
+ void *write_buf = NULL;
+ int hwsync_cost_bytes = 0;
+ if (adev->hw_sync_mode == 1) {
+ int64_t cur_pts = 0xffffffff;
+ int outsize = 0;
+ char tempbuf[128];
+ ALOGV("before aml_audio_hwsync_find_frame bytes %d\n", bytes);
+ hwsync_cost_bytes = aml_audio_hwsync_find_frame(out, buffer, bytes, &cur_pts, &outsize);
+ ALOGV("after aml_audio_hwsync_find_frame bytes remain %d,cost %d,outsize %d,pts %llx\n",
+ bytes - hwsync_cost_bytes, hwsync_cost_bytes, outsize, cur_pts);
+ //TODO,skip 3 frames after flush, to tmp fix seek pts discontinue issue.need dig more
+ // to find out why seek ppint pts frame is remained after flush.WTF.
+ if (out->skip_frame > 0) {
+ out->skip_frame--;
+ ALOGI("skip pts@%llx,cur frame size %d,cost size %d\n", cur_pts, outsize, hwsync_cost_bytes);
+ pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&out->lock);
+ return hwsync_cost_bytes;
+ }
+ if (cur_pts != 0xffffffff && outsize > 0) {
+ // if we got the frame body,which means we get a complete frame.
+ //we take this frame pts as the first apts.
+ //this can fix the seek discontinue,we got a fake frame,which maybe cached before the seek
+ if (p_hwsync->first_apts_flag == false) {
+ p_hwsync->first_apts_flag = true;
+ p_hwsync->first_apts = cur_pts;
+ sprintf(tempbuf, "AUDIO_START:0x%llx", cur_pts & 0xffffffff);
+ ALOGI("tsync -> %s,frame size %d", tempbuf, outsize);
+ if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) {
+ ALOGE("set AUDIO_START failed \n");
+ }
+ } else {
+ long apts;
+ unsigned long latency = out_get_latency(out) * 90;
+ // check PTS discontinue, which may happen when audio track switching
+ // discontinue means PTS calculated based on first_apts and frame_write_sum
+ // does not match the timestamp of next audio samples
+ if (cur_pts > latency) {
+ apts = (unsigned long)cur_pts - latency;
+ } else {
+ apts = 0;
+ }
+ if (0) { //abs(cur_pts -apts) > APTS_DISCONTINUE_THRESHOLD) {
+ ALOGI("HW sync PTS discontinue, 0x%lx->0x%llx(from header) diff %llx,last apts %llx(from header)",
+ apts, cur_pts, llabs(cur_pts - apts), p_hwsync->last_apts_from_header);
+ p_hwsync->first_apts = cur_pts;
+ sprintf(tempbuf, "AUDIO_TSTAMP_DISCONTINUITY:0x%llx", cur_pts);
+ if (sysfs_set_sysfs_str(TSYNC_EVENT, tempbuf) == -1) {
+ ALOGE("unable to open file %s,err: %s", TSYNC_EVENT, strerror(errno));
+ }
+ } else {
+ long pcr = 0;
+ if (get_sysfs_int16(TSYNC_PCRSCR, &pcr) == 0) {
+ uint32_t apts_cal = apts & 0xffffffff;
+ if (abs(pcr - apts) < SYSTIME_CORRECTION_THRESHOLD) {
+ // do nothing
+ }
+ // limit the gap handle to 0.5~5 s.
+ else if ((apts - pcr) > APTS_DISCONTINUE_THRESHOLD_MIN && (apts - pcr) < APTS_DISCONTINUE_THRESHOLD_MAX) {
+ int insert_size = 0;
+ int once_write_size = 0;
+ if (out->codec_type == TYPE_EAC3) {
+ insert_size = abs(apts - pcr) / 90 * 48 * 4 * 4;
+ } else {
+ insert_size = abs(apts - pcr) / 90 * 48 * 4;
+ }
+ insert_size = insert_size & (~63);
+ ALOGI("audio gap %d ms ,need insert data %d\n", abs(apts - pcr) / 90, insert_size);
+ char *insert_buf = (char*)malloc(8192);
+ if (insert_buf == NULL) {
+ ALOGE("malloc size failed \n");
+ pthread_mutex_unlock(&adev->lock);
+ goto exit;
+ }
+ memset(insert_buf, 0, 8192);
+ while (insert_size > 0) {
+ once_write_size = insert_size > 8192 ? 8192 : insert_size;
+ ret = pcm_write(out->pcm, (void *) insert_buf, once_write_size);
+ if (ret != 0) {
+ ALOGE("pcm write failed\n");
+ free(insert_buf);
+ pthread_mutex_unlock(&adev->lock);
+ goto exit;
+ }
+ insert_size -= once_write_size;
+ }
+ free(insert_buf);
+ }
+ //audio pts smaller than pcr,need skip frame.
+ else if ((pcr - apts) > APTS_DISCONTINUE_THRESHOLD_MIN && (pcr - apts) < APTS_DISCONTINUE_THRESHOLD_MAX) {
+ //we assume one frame duration is 32 ms for DD+(6 blocks X 1536 frames,48K sample rate)
+ if (out->codec_type == TYPE_EAC3 && outsize > 0) {
+ ALOGI("audio slow 0x%lx,skip frame @pts 0x%llx,pcr 0x%lx,cur apts 0x%lx\n", (pcr - apts), cur_pts, pcr, apts);
+ out->frame_skip_sum += 1536;
+ bytes = outsize;
+ pthread_mutex_unlock(&adev->lock);
+ goto exit;
+ }
+ } else {
+ sprintf(tempbuf, "0x%lx", apts);
+ ALOGI("tsync -> reset pcrscr 0x%lx -> 0x%lx, %s big,diff %d ms", pcr, apts, apts > pcr ? "apts" : "pcr", abs(apts - pcr) / 90);
+#if 0
+ int ret_val = sysfs_set_sysfs_str(TSYNC_APTS, tempbuf);
+ if (ret_val == -1) {
+ ALOGE("unable to open file %s,err: %s", TSYNC_APTS, strerror(errno));
+ }
+#endif
+ }
+ }
+ }
+ }
+ }
+ if (outsize > 0) {
+ in_frames = outsize / frame_size;
+ write_buf = p_hwsync->hw_sync_body_buf;
+ } else {
+ bytes = hwsync_cost_bytes;
+ pthread_mutex_unlock(&adev->lock);
+ goto exit;
+ }
+ } else {
+ write_buf = (void *) buffer;
+ }
+ pthread_mutex_unlock(&adev->lock);
+ out_frames = in_frames;
+ buf = (void *) write_buf;
+ if (getprop_bool("media.hdmihal.outdump")) {
+ FILE *fp1 = fopen("/data/tmp/hdmi_audio_out.pcm", "a+");
+ if (fp1) {
+ int flen = fwrite((char *)buffer, 1, out_frames * frame_size, fp1);
+ LOGFUNC("flen = %d---outlen=%d ", flen, out_frames * frame_size);
+ fclose(fp1);
+ } else {
+ LOGFUNC("could not open file:/data/hdmi_audio_out.pcm");
+ }
+ }
+ if (codec_type_is_raw_data(out->codec_type) && !(out->flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) {
+ //here to do IEC61937 pack
+ ALOGV("IEC61937 write size %d,hw_sync_mode %d,flag %x\n", out_frames * frame_size, adev->hw_sync_mode, out->flags);
+ if (out->codec_type > 0) {
+ // compressed audio DD/DD+
+ bytes = spdifenc_write((void *) buf, out_frames * frame_size);
+ //need return actual size of this burst write
+ if (adev->hw_sync_mode == 1) {
+ bytes = hwsync_cost_bytes;
+ }
+ ALOGV("spdifenc_write return %d\n", bytes);
+ if (out->codec_type == TYPE_EAC3) {
+ out->frame_write_sum = spdifenc_get_total() / 16 + out->spdif_enc_init_frame_write_sum;
+ } else {
+ out->frame_write_sum = spdifenc_get_total() / 4 + out->spdif_enc_init_frame_write_sum;
+ }
+ ALOGV("out %p,spdifenc_get_total() / 4 %lld\n", out, spdifenc_get_total() / 16);
+ }
+ goto exit;
+ }
+ if (!out->standby) {
+ if (out->multich == 8) {
+ int *p32 = NULL;
+ short *p16 = (short *) buf;
+ short *p16_temp;
+ int i, NumSamps;
+ NumSamps = out_frames * frame_size / sizeof(short);
+ p32 = malloc(NumSamps * sizeof(int));
+ if (p32 != NULL) {
+ //here to swap the channnl data here
+ //actual now:L,missing,R,RS,RRS,,LS,LRS,missing
+ //expect L,C,R,RS,RRS,LRS,LS,LFE (LFE comes from to center)
+ //actual audio data layout L,R,C,none/LFE,LRS,RRS,LS,RS
+ p16_temp = (short *) p32;
+ for (i = 0; i < NumSamps; i = i + 8) {
+ p16_temp[0 + i]/*L*/ = p16[0 + i];
+ p16_temp[1 + i]/*R*/ = p16[1 + i];
+ p16_temp[2 + i] /*LFE*/ = p16[3 + i];
+ p16_temp[3 + i] /*C*/ = p16[2 + i];
+ p16_temp[4 + i] /*LS*/ = p16[6 + i];
+ p16_temp[5 + i] /*RS*/ = p16[7 + i];
+ p16_temp[6 + i] /*LRS*/ = p16[4 + i];
+ p16_temp[7 + i]/*RRS*/ = p16[5 + i];
+ }
+ memcpy(p16, p16_temp, NumSamps * sizeof(short));
+ for (i = 0; i < NumSamps; i++) { //suppose 16bit/8ch PCM
+ p32[i] = p16[i] << 16;
+ }
+ ret = pcm_write(out->pcm, (void *) p32, NumSamps * 4);
+ free(p32);
+ }
+ } else if (out->multich == 6) {
+ int *p32 = NULL;
+ short *p16 = (short *) buf;
+ short *p16_temp;
+ int i, j, NumSamps, real_samples;
+ real_samples = out_frames * frame_size / sizeof(short);
+ NumSamps = real_samples * 8 / 6;
+ //ALOGI("6ch to 8 ch real %d, to %d,bytes %d,frame size %d\n",real_samples,NumSamps,bytes,frame_size);
+ p32 = malloc(NumSamps * sizeof(int));
+ if (p32 != NULL) {
+ p16_temp = (short *) p32;
+ for (i = 0; i < real_samples; i = i + 6) {
+ p16_temp[0 + i]/*L*/ = p16[0 + i];
+ p16_temp[1 + i]/*R*/ = p16[1 + i];
+ p16_temp[2 + i] /*LFE*/ = p16[3 + i];
+ p16_temp[3 + i] /*C*/ = p16[2 + i];
+ p16_temp[4 + i] /*LS*/ = p16[4 + i];
+ p16_temp[5 + i] /*RS*/ = p16[5 + i];
+ }
+ memcpy(p16, p16_temp, real_samples * sizeof(short));
+ memset(p32, 0, NumSamps * sizeof(int));
+ for (i = 0, j = 0; j < NumSamps; i = i + 6, j = j + 8) { //suppose 16bit/8ch PCM
+ p32[j] = p16[i] << 16;
+ p32[j + 1] = p16[i + 1] << 16;
+ p32[j + 2] = p16[i + 2] << 16;
+ p32[j + 3] = p16[i + 3] << 16;
+ p32[j + 4] = p16[i + 4] << 16;
+ p32[j + 5] = p16[i + 5] << 16;
+ }
+ ret = pcm_write(out->pcm, (void *) p32, NumSamps * 4);
+ free(p32);
+ }
+ } else {
+#if 0
+ codec_type =
+ get_sysfs_int("/sys/class/audiodsp/digital_codec");
+ samesource_flag =
+ get_sysfs_int("/sys/class/audiodsp/audio_samesource");
+ if (out->last_codec_type > 0 && codec_type != out->last_codec_type) {
+ samesource_flag = 1;
+ }
+ if (samesource_flag == 1 && codec_type) {
+ ALOGI
+ ("to disable same source,need reset alsa,last %d,type %d,same source flag %d ,\n",
+ out->last_codec_type, codec_type, samesource_flag);
+ out->last_codec_type = codec_type;
+ pcm_stop(out->pcm);
+ }
+#endif
+ ALOGV("write size %d\n", out_frames * frame_size);
+ ret = pcm_write(out->pcm, (void *) buf, out_frames * frame_size);
+ if (ret == 0) {
+ out->frame_write_sum += out_frames;
+ }
+ }
+ }
+exit:
+ total_frame = out->frame_write_sum + out->frame_skip_sum;
+ latency_frames = out_get_latency(out) * out->config.rate / 1000;
+ if (total_frame >= latency_frames) {
+ out->last_frames_postion = total_frame - latency_frames;
+ } else {
+ out->last_frames_postion = total_frame;
+ }
+ pthread_mutex_unlock(&out->lock);
+ if (ret != 0) {
+ usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
+ out_get_sample_rate(&stream->common));
+ }
+ return bytes;
+}
+
+static ssize_t out_write_tv(struct audio_stream_out *stream, const void* buffer,
+ size_t bytes)
+{
+ // TV temporarily use legacy out write.
+ /* TODO: add TV platform specific write here */
+ return out_write_legacy(stream, buffer, bytes);
+}
+
static int out_get_render_position(const struct audio_stream_out *stream,
uint32_t *dsp_frames)
{
@@ -1978,8 +2441,8 @@ static void release_buffer(struct resampler_buffer_provider *buffer_provider,
static int start_input_stream(struct aml_stream_in *in)
{
int ret = 0;
- unsigned int card = CARD_AMLOGIC_DEFAULT;
- unsigned int port = PORT_MM;
+ unsigned int card = CARD_AMLOGIC_BOARD;
+ unsigned int port = PORT_I2S;
struct aml_audio_device *adev = in->dev;
LOGFUNC("%s(need_echo_reference=%d, channels=%d, rate=%d, requested_rate=%d, mode= %d)",
@@ -1996,11 +2459,11 @@ static int start_input_stream(struct aml_stream_in *in)
ALOGV("%s(in->requested_rate=%d, in->config.rate=%d)",
__FUNCTION__, in->requested_rate, in->config.rate);
if (adev->in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
- port = get_pcm_bt_port();
+ port = PORT_PCM;
} else if (getprop_bool("sys.hdmiIn.Capture")) {
- port = get_spdif_port();
+ port = PORT_SPDIF;
} else {
- port = PORT_MM;
+ port = PORT_I2S;
}
LOGFUNC("*%s, open card(%d) port(%d)-------", __FUNCTION__, card, port);
in->config.period_size = CAPTURE_PERIOD_SIZE;
@@ -2419,9 +2882,8 @@ static ssize_t read_frames(struct aml_stream_in *in, void *buffer, ssize_t frame
&frames_rd);
} else {
struct resampler_buffer buf = {
- { raw : NULL, },
-frame_count :
- frames_rd,
+ { .raw = NULL, },
+ .frame_count = frames_rd,
};
get_next_buffer(&in->buf_provider, &buf);
if (buf.raw != NULL) {
@@ -2669,17 +3131,20 @@ exit:
static int adev_open_output_stream(struct audio_hw_device *dev,
audio_io_handle_t handle __unused,
- audio_devices_t devices __unused,
- audio_output_flags_t flags __unused,
+ audio_devices_t devices,
+ audio_output_flags_t flags,
struct audio_config *config,
- struct audio_stream_out **stream_out)
+ struct audio_stream_out **stream_out,
+ const char *address __unused)
{
struct aml_audio_device *ladev = (struct aml_audio_device *)dev;
struct aml_stream_out *out;
int channel_count = popcount(config->channel_mask);
+ int digital_codec;
+ bool direct = false;
int ret;
- LOGFUNC("**enter %s(devices=0x%04x,format=%d, ch=0x%04x, SR=%d, flags=0x%x)", __FUNCTION__, devices,
+ ALOGI("**enter %s(devices=0x%04x,format=%#x, ch=0x%04x, SR=%d, flags=0x%x)", __FUNCTION__, devices,
config->format, config->channel_mask, config->sample_rate, flags);
out = (struct aml_stream_out *)calloc(1, sizeof(struct aml_stream_out));
@@ -2687,13 +3152,66 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
return -ENOMEM;
}
+ out->flags = flags;
+ if (getprop_bool("ro.platform.has.tvuimode")) {
+ out->is_tv_platform = 1;
+ }
+ out->config = pcm_config_out;
+
+ if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
+ out->stream.common.get_channels = out_get_channels;
+ out->stream.common.get_format = out_get_format;
+
+ if (out->is_tv_platform)
+ out->stream.write = out_write_tv;
+ else
+ out->stream.write = out_write;
+ out->stream.common.standby = out_standby;
+
+ out->hal_rate = out->config.rate;
+ config->format = out_get_format(&out->stream.common);
+ config->channel_mask = out_get_channels(&out->stream.common);
+ config->sample_rate = out_get_sample_rate(&out->stream.common);
+ } else if (flags & AUDIO_OUTPUT_FLAG_DIRECT) {
+ out->stream.common.get_channels = out_get_channels_direct;
+ out->stream.common.get_format = out_get_format_direct;
+ out->stream.write = out_write_direct;
+ out->stream.common.standby = out_standby_direct;
+ //out->config = pcm_config_out_direct;
+ out->hal_channel_mask = config->channel_mask;
+ if (config->sample_rate == 0) {
+ config->sample_rate = 48000;
+ }
+ out->config.rate = out->hal_rate = config->sample_rate;
+ out->hal_format = config->format;
+ digital_codec = get_codec_type(config->format);
+ if (digital_codec == TYPE_EAC3) {
+ out->config.period_size = pcm_config_out.period_size * 2;
+ } else if (digital_codec == TYPE_TRUE_HD || digital_codec == TYPE_DTS_HD) {
+ out->config.period_size = pcm_config_out.period_size * 4 * 2;
+ }
+
+ if (channel_count > 2) {
+ ALOGI("[adev_open_output_stream]: out/%p channel/%d\n", out,
+ channel_count);
+ out->multich = channel_count;
+ out->config.channels = channel_count;
+ }
+ if (codec_type_is_raw_data(digital_codec)) {
+ ALOGI("for raw audio output,force alsa stereo output\n");
+ out->config.channels = 2;
+ out->multich = 2;
+ }
+ } else if(flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC){
+ // TODO: add hwsync write here
+ //out->stream.write = out_write_hwsync;
+ }
+
out->stream.common.get_sample_rate = out_get_sample_rate;
out->stream.common.set_sample_rate = out_set_sample_rate;
out->stream.common.get_buffer_size = out_get_buffer_size;
- out->stream.common.get_channels = out_get_channels;
- out->stream.common.get_format = out_get_format;
out->stream.common.set_format = out_set_format;
- out->stream.common.standby = out_standby;
+ //out->stream.common.standby = out_standby;
out->stream.common.dump = out_dump;
out->stream.common.set_parameters = out_set_parameters;
out->stream.common.get_parameters = out_get_parameters;
@@ -2701,15 +3219,12 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->stream.common.remove_audio_effect = out_remove_audio_effect;
out->stream.get_latency = out_get_latency;
out->stream.set_volume = out_set_volume;
- out->stream.write = out_write;
out->stream.get_render_position = out_get_render_position;
out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
out->stream.get_presentation_position = out_get_presentation_position;
out->stream.pause = out_pause;
out->stream.resume = out_resume;
out->stream.flush = out_flush;
- out->config = pcm_config_out;
- out->is_tv_platform = 0;
out->volume_l = 1.0;
out->volume_r = 1.0;
out->dev = ladev;
@@ -2717,7 +3232,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
out->frame_write_sum = 0;
out->hw_sync_mode = false;
out->first_apts_flag = false;
- ALOGI("adev_open_output_stream stream %p,flag %d\n", out, flags);
+ //out->hal_rate = out->config.rate;
if (0/*flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC*/) {
out->hw_sync_mode = true;
ALOGI("Output stream open with AUDIO_OUTPUT_FLAG_HW_AV_SYNC");
@@ -2731,18 +3246,14 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
* guaranteed to be called after an output stream is opened.
*/
- config->format = out_get_format(&out->stream.common);
- config->channel_mask = out_get_channels(&out->stream.common);
- config->sample_rate = out_get_sample_rate(&out->stream.common);
- LOGFUNC("**leave %s(devices=0x%04x,format=%d, ch=0x%04x, SR=%d)", __FUNCTION__, devices,
+ LOGFUNC("**leave %s(devices=0x%04x,format=%#x, ch=0x%04x, SR=%d)", __FUNCTION__, devices,
config->format, config->channel_mask, config->sample_rate);
*stream_out = &out->stream;
- if (getprop_bool("ro.platform.has.tvuimode")) {
+ if (out->is_tv_platform) {
out->config.channels = 8;
out->config.format = PCM_FORMAT_S32_LE;
- out->is_tv_platform = 1;
out->tmp_buffer_8ch = malloc(out->config.period_size * 4 * 8);
if (out->tmp_buffer_8ch == NULL) {
ALOGE("cannot malloc memory for out->tmp_buffer_8ch");
@@ -2940,7 +3451,9 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
audio_devices_t devices,
struct audio_config *config,
struct audio_stream_in **stream_in,
- audio_input_flags_t flags __unused)
+ audio_input_flags_t flags __unused,
+ const char *address __unused,
+ audio_source_t source __unused)
{
struct aml_audio_device *ladev = (struct aml_audio_device *)dev;
struct aml_stream_in *in;
@@ -3071,7 +3584,7 @@ static int adev_open(const hw_module_t* module, const char* name,
hw_device_t** device)
{
struct aml_audio_device *adev;
- int card = CARD_AMLOGIC_DEFAULT;
+ int card = CARD_AMLOGIC_BOARD;
int ret;
if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
return -EINVAL;
@@ -3124,7 +3637,7 @@ static int adev_open(const hw_module_t* module, const char* name,
return 0;
}
-static const struct hw_module_methods_t hal_module_methods = {
+static struct hw_module_methods_t hal_module_methods = {
.open = adev_open,
};
diff --git a/audio_hw.h b/audio_hw.h
index b7e1342..cd82df3 100644
--- a/audio_hw.h
+++ b/audio_hw.h
@@ -1,4 +1,8 @@
#ifndef _AUDIO_HW_H_
+
+#include <audio_utils/resampler.h>
+#include "audio_hwsync.h"
+
#define _AUDIO_HW_H_
#define _AUDIO_HW_H_
/* ALSA cards for AML */
@@ -28,4 +32,132 @@ static unsigned int DEFAULT_OUT_SAMPLING_RATE = 48000;
#define MM_FULL_POWER_SAMPLING_RATE 48000
/* sampling rate when using VX port for narrow band */
#define VX_NB_SAMPLING_RATE 8000
+
+enum {
+ TYPE_PCM = 0,
+ TYPE_AC3 = 2,
+ TYPE_DTS = 3,
+ TYPE_EAC3 = 4,
+ TYPE_DTS_HD = 5 ,
+ TYPE_MULTI_PCM = 6,
+ TYPE_TRUE_HD = 7,
+ TYPE_DTS_HD_MA = 8,//should not used after we unify DTS-HD&DTS-HD MA
+ TYPE_PCM_HIGH_SR = 9,
+};
+
+#define AML_HAL_MIXER_BUF_SIZE 64*1024
+struct aml_hal_mixer {
+ unsigned char start_buf[AML_HAL_MIXER_BUF_SIZE];
+ unsigned int wp;
+ unsigned int rp;
+ unsigned int buf_size;
+ unsigned char need_cache_flag;//flag to check if need cache some data before write to mix
+ pthread_mutex_t lock;
+};
+
+#define MAX_STREAM_NUM 5
+
+struct aml_audio_device {
+ struct audio_hw_device hw_device;
+
+ pthread_mutex_t lock; /* see note below on mutex acquisition order */
+ pthread_mutex_t pcm_write_lock;
+ int mode;
+ audio_devices_t in_device;
+ audio_devices_t out_device;
+ int in_call;
+ struct aml_stream_in *active_input;
+ struct aml_stream_out *active_output[MAX_STREAM_NUM];
+ unsigned char active_output_count;
+ bool mic_mute;
+ unsigned int card;
+ struct audio_route *ar;
+ struct echo_reference_itfe *echo_reference;
+ bool low_power;
+ struct aml_stream_out *hwsync_output;
+ struct aml_hal_mixer hal_mixer;
+ struct pcm *pcm;
+ bool hw_sync_mode;
+ audio_hwsync_t hwsync;
+};
+
+struct aml_stream_out {
+ struct audio_stream_out stream;
+ /* see note below on mutex acquisition order */
+ pthread_mutex_t lock;
+ /* config which set to ALSA device */
+ struct pcm_config config;
+ /* channel mask exposed to AudioFlinger. */
+ audio_channel_mask_t hal_channel_mask;
+ /* format mask exposed to AudioFlinger. */
+ audio_format_t hal_format;
+ /* samplerate exposed to AudioFlinger. */
+ unsigned int hal_rate;
+ audio_output_flags_t flags;
+ struct pcm *pcm;
+ struct resampler_itfe *resampler;
+ char *buffer;
+ size_t buffer_frames;
+ bool standby;
+ struct echo_reference_itfe *echo_reference;
+ struct aml_audio_device *dev;
+ int write_threshold;
+ bool low_power;
+ unsigned multich;
+ int codec_type;
+ uint64_t frame_write_sum;
+ uint64_t frame_skip_sum;
+ uint64_t last_frames_postion;
+ uint8_t hw_sync_header[16];
+ int hw_sync_header_cnt;
+ int hw_sync_state;
+ int hw_sync_body_cnt;
+ uint64_t spdif_enc_init_frame_write_sum;
+ uint64_t bytes_write_total;
+ int skip_frame;
+ uint8_t body_align[64];
+ uint8_t body_align_cnt;
+ int32_t *tmp_buffer_8ch;
+ int is_tv_platform;
+ void *audioeffect_tmp_buffer;
+ int has_SRS_lib;
+ int has_EQ_lib;
+ unsigned char pause_status;
+ bool hw_sync_mode;
+ bool first_apts_flag;//flag to indicate set first apts
+ uint64_t first_apts;
+ int64_t last_apts_from_header;
+ int has_aml_IIR_lib;
+ float volume_l;
+ float volume_r;
+};
+
+#define MAX_PREPROCESSORS 3 /* maximum one AGC + one NS + one AEC per input stream */
+struct aml_stream_in {
+ struct audio_stream_in stream;
+ pthread_mutex_t lock; /* see note below on mutex acquisition order */
+ struct pcm_config config;
+ struct pcm *pcm;
+ int device;
+ struct resampler_itfe *resampler;
+ struct resampler_buffer_provider buf_provider;
+ int16_t *buffer;
+ size_t frames_in;
+ unsigned int requested_rate;
+ bool standby;
+ int source;
+ struct echo_reference_itfe *echo_reference;
+ bool need_echo_reference;
+ effect_handle_t preprocessors[MAX_PREPROCESSORS];
+ int num_preprocessors;
+ int16_t *proc_buf;
+ size_t proc_buf_size;
+ size_t proc_frames_in;
+ int16_t *ref_buf;
+ size_t ref_buf_size;
+ size_t ref_frames_in;
+ int read_status;
+ struct aml_audio_device *dev;
+};
+
#endif
diff --git a/audio_hw_utils.c b/audio_hw_utils.c
index f0bf70c..5dc53ca 100644
--- a/audio_hw_utils.c
+++ b/audio_hw_utils.c
@@ -1,3 +1,6 @@
+#define LOG_TAG "audio_hw_utils"
+#define LOG_NDEBUG 0
+
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
@@ -20,20 +23,18 @@
#include "audio_hw_utils.h"
#include "audio_hwsync.h"
-#include "hdmi_audio_hw.h"
+#include "audio_hw.h"
-#define LOG_TAG "audio_hw_utils"
-#define LOG_NDEBUG 0
#ifdef LOG_NDEBUG_FUNCTION
#define LOGFUNC(...) ((void)0)
#else
#define LOGFUNC(...) (ALOGD(__VA_ARGS__))
#endif
-int get_sysfs_int16(const char *path,unsigned *value)
+int get_sysfs_int16(const char *path, int *value)
{
int fd;
char valstr[64];
- unsigned val = 0;
+ int val = 0;
fd = open(path, O_RDONLY);
if (fd >= 0) {
memset(valstr, 0, 64);
@@ -44,7 +45,7 @@ int get_sysfs_int16(const char *path,unsigned *value)
ALOGE("unable to open file %s\n", path);
return -1;
}
- if (sscanf(valstr, "0x%lx", &val) < 1) {
+ if (sscanf(valstr, "0x%x", &val) < 1) {
ALOGE("unable to get pts from: %s", valstr);
return -1;
}
@@ -123,6 +124,7 @@ unsigned char codec_type_is_raw_data(int type)
case TYPE_TRUE_HD:
case TYPE_DTS:
case TYPE_DTS_HD:
+ case TYPE_DTS_HD_MA:
return 1;
default:
return 0;
@@ -132,19 +134,19 @@ unsigned char codec_type_is_raw_data(int type)
int get_codec_type(int format)
{
switch (format) {
- case AUDIO_FORMAT_AC3:
+ case AUDIO_FORMAT_AC3:
return TYPE_AC3;
- case AUDIO_FORMAT_E_AC3:
+ case AUDIO_FORMAT_E_AC3:
return TYPE_EAC3;
- case AUDIO_FORMAT_DTS:
+ case AUDIO_FORMAT_DTS:
return TYPE_DTS;
- case AUDIO_FORMAT_DTS_HD:
- return TYPE_DTS_HD;
- case AUDIO_FORMAT_TRUEHD:
- return TYPE_TRUE_HD;
- case AUDIO_FORMAT_PCM:
+ case AUDIO_FORMAT_DTS_HD:
+ return TYPE_DTS_HD_MA;
+ case AUDIO_FORMAT_TRUEHD:
+ return TYPE_TRUE_HD;
+ case AUDIO_FORMAT_PCM:
return TYPE_PCM;
- default:
+ default:
return TYPE_PCM;
}
}
diff --git a/audio_hw_utils.h b/audio_hw_utils.h
index 1585009..9bcdc9c 100644
--- a/audio_hw_utils.h
+++ b/audio_hw_utils.h
@@ -1,6 +1,6 @@
#ifndef _AUDIO_HW_UTILS_H_
#define _AUDIO_HW_UTILS_H_
-int get_sysfs_int16(const char *path,unsigned *value);
+int get_sysfs_int16(const char *path, int *value);
int sysfs_set_sysfs_str(const char *path, const char *val);
int get_sysfs_int (const char *path);
int mystrstr(char *mystr,char *substr) ;
diff --git a/audio_hwsync.c b/audio_hwsync.c
index 8562d0b..12f4972 100644
--- a/audio_hwsync.c
+++ b/audio_hwsync.c
@@ -21,7 +21,7 @@
#include "audio_hwsync.h"
#include "audio_hw_utils.h"
#include "audio_hw.h"
-#include "hdmi_audio_hw.h"
+//#include "hdmi_audio_hw.h"
static uint32_t aml_hwsync_out_get_latency(const struct audio_stream_out *stream)
{
struct aml_stream_out *out = (struct aml_stream_out *)stream;
@@ -36,7 +36,7 @@ static uint32_t aml_hwsync_out_get_latency(const struct audio_stream_out *stream
if (ret < 0) {
return whole_latency;
}
- if (out->format == AUDIO_FORMAT_E_AC3) {
+ if (out->hal_format == AUDIO_FORMAT_E_AC3) {
frames /= 4;
}
return (uint32_t)((frames * 1000) / out->config.rate);
diff --git a/spdifenc_wrap.cpp b/spdifenc_wrap.cpp
index ec4f6b6..469169c 100644
--- a/spdifenc_wrap.cpp
+++ b/spdifenc_wrap.cpp
@@ -5,6 +5,12 @@
#include <audio_utils/spdif/SPDIFEncoder.h>
#include <tinyalsa/asoundlib.h>
#include <cutils/properties.h>
+
+extern "C"
+{
+#include "audio_hw_utils.h"
+}
+#if 0
static int
getprop_bool(const char *path)
{
@@ -18,6 +24,8 @@ getprop_bool(const char *path)
}
return 0;
}
+#endif
+extern "C" int getprop_boll(const char *path);
namespace android
{
class MySPDIFEncoder : public SPDIFEncoder
diff --git a/spdifenc_wrap.h b/spdifenc_wrap.h
new file mode 100644
index 0000000..5d18df3
--- a/dev/null
+++ b/spdifenc_wrap.h
@@ -0,0 +1,16 @@
+#ifndef __SPDIFENC_WRAP_H__
+#define __SPDIFENC_WRAP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int spdifenc_init(struct pcm *mypcm);
+int spdifenc_write(const void *buffer, size_t numBytes);
+uint64_t spdifenc_get_total(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__SPDIFENC_WRAP_H__ \ No newline at end of file