You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

522 lines
13 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. Technologies Co., Ltd. 2020-2020. All rights reserved.
* Description: audio hal wrapper for SDK source file.
* Author: yinyingcai
* Create: 2020-05-11
* Notes: NA
* History: 2020-05-11 yinyingcai for CodingStyle
*/
#define LOG_TAG "audio_hal_wrapper"
#define LOG_NDEBUG 0
#include "aiao_wrap.h"
#include <log/log.h>
#include <math.h>
#include <unistd.h>
#include <securec.h>
#include "td_type.h"
#include "uapi_version.h"
#include "uapi_amp.h"
#include "vnaudio_dbg.h"
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
#include "uapi_system.h"
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
#include "soc_errno.h"
#endif
#define AOP_LOW_LATENCYMS 30
#define AOP_DEFAULT_LATENCYMS 40
#define ADEC_DDP_CERTDEEP_INPUT_BUFFER_SIZE (20 * 1024)
// for volume shaper to dB
#define MIN_SUPPORT_VOLUME_DB (-81)
// hci
#define CAST_PCM_FRAME_MAXNUM 4
#define CAST_SLEEP_MS 10
#define BYTES_PER_SAMPLE 4
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
static uapi_snd_out_port get_outport_type(hal_snd_out_port out_port)
{
static uapi_snd_out_port ports[] = {
UAPI_SND_OUT_PORT_DAC0,
UAPI_SND_OUT_PORT_DAC1,
UAPI_SND_OUT_PORT_DAC2,
UAPI_SND_OUT_PORT_DAC3,
UAPI_SND_OUT_PORT_I2S0,
UAPI_SND_OUT_PORT_I2S1,
UAPI_SND_OUT_PORT_I2S2,
UAPI_SND_OUT_PORT_I2S3,
UAPI_SND_OUT_PORT_I2S4,
UAPI_SND_OUT_PORT_SPDIF0,
UAPI_SND_OUT_PORT_HDMITX0,
UAPI_SND_OUT_PORT_HDMITX1,
UAPI_SND_OUT_PORT_ARC0,
UAPI_SND_OUT_PORT_ARC1,
UAPI_SND_OUT_PORT_ALL,
UAPI_SND_OUT_PORT_MAX,
};
if (out_port >= HAL_SND_OUT_PORT_DAC0 && out_port <= HAL_SND_OUT_PORT_MAX) {
return ports[out_port];
} else {
ALOGE("Invalid outport type");
return UAPI_SND_OUT_PORT_ALL;
}
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_init_hal_sound(void)
{
int32_t ret;
uapi_snd_attr stAttr;
ret = memset_s(&stAttr, sizeof(uapi_snd_attr), 0, sizeof(uapi_snd_attr));
if (ret != 0) {
ALOGE("memset_s uapi_snd_attr failed (0x%x)", ret);
return ret;
}
ret = uapi_sys_init();
if (ret != TD_SUCCESS) {
ALOGE("call uapi_sys_init failed(0x%x)", ret);
return ret;
}
ret = uapi_snd_init();
if (ret != TD_SUCCESS) {
ALOGE("call uapi_snd_init failed(0x%x)", ret);
return ret;
}
/* Do not Deinit when failed */
ret = uapi_snd_get_default_open_attr(UAPI_SND_0, &stAttr);
if (ret != TD_SUCCESS) {
ALOGE("call uapi_snd_get_default_open_attr failed(0x%x)", ret);
int tmp_ret = uapi_snd_deinit();
if (tmp_ret != TD_SUCCESS) {
ALOGE("call uapi_snd_deinit failed(0x%x)", tmp_ret);
}
return ret;
}
ret = uapi_snd_open(UAPI_SND_0, &stAttr);
if (ret != TD_SUCCESS) {
ALOGE("call uapi_snd_open failed(0x%x)", ret);
int tmp_ret = uapi_snd_deinit();
if (tmp_ret != TD_SUCCESS) {
ALOGE("call uapi_snd_deinit failed(0x%x)", tmp_ret);
}
return ret;
}
return TD_SUCCESS;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
void wraper_deinit_hal_sound(void)
{
int ret;
ret = uapi_snd_close(UAPI_SND_0);
if (ret != TD_SUCCESS) {
ALOGE("call uapi_snd_close failed(0x%x)", ret);
}
ret = uapi_snd_deinit();
if (ret != TD_SUCCESS) {
ALOGE("call uapi_snd_deinit failed(0x%x)", ret);
}
ret = uapi_sys_deinit();
if (ret != TD_SUCCESS) {
ALOGE("call uapi_snd_deinit failed(0x%x)", ret);
}
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_set_adec_buffer_size(uint32_t havplay __unused, uint32_t adecMinBufSize __unused,
uint32_t adecOutFrameCnt __unused)
{
return 0;
}
#endif
int wraper_set_adec_attr(uint32_t havplay __unused, const struct audio_attr* attr __unused)
{
return 0;
}
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_set_sync_attr(uint32_t havplay __unused, hal_sync_attr sync_attr __unused)
{
return 0;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_create_track(uint32_t *phtrack __unused, hal_audio_track_attr track_attr __unused,
hal_snd_track_type track_type __unused)
{
return 0;
}
#endif
int wraper_register_acodec_lib(const char *fileName __unused)
{
return 0;
}
int wraper_get_buf(uint32_t hAvplay __unused, uint32_t fragmentsize __unused)
{
return 0;
}
int wraper_put_buf(const uint8_t* pData __unused, uint32_t hAvplay __unused, uint32_t fragmentsize __unused,
uint32_t u32Pts __unused)
{
return 0;
}
int wraper_start_avplay(uint32_t havplay __unused)
{
return 0;
}
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_create_avplay(uint32_t *sync_source __unused)
{
return 0;
}
#endif
int wraper_destroy_avplay(uint32_t sync_source __unused)
{
return 0;
}
int wraper_init_snd(void)
{
return 0;
}
int wraper_deinit_snd(void)
{
return 0;
}
int wraper_init_avplay(void)
{
return 0;
}
int wraper_deinit_avplay(void)
{
return 0;
}
int wraper_open_chan(uint32_t hAvplay __unused)
{
return 0;
}
int wraper_close_chan(uint32_t hAvplay __unused)
{
return 0;
}
int wraper_destroy_track(uint32_t hTrack __unused)
{
return 0;
}
int wraper_attach_snd(uint32_t hTrack __unused, uint32_t hAvplay __unused)
{
return 0;
}
int wraper_detach_snd(uint32_t hTrack __unused, uint32_t hAvplay __unused)
{
return 0;
}
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_stop_avplay(uint32_t hAvplay __unused)
{
return 0;
}
#endif
int wraper_set_snd_default_latency(void)
{
return 0;
}
int wraper_pause_avplay(uint32_t hAvplay __unused)
{
return 0;
}
int wraper_resume_avplay(uint32_t hAvplay __unused)
{
return 0;
}
int wraper_flush_avplay(uint32_t hAvplay __unused)
{
return 0;
}
int wraper_get_audio_playtime(uint32_t hAvplay __unused, uint32_t *pu32PlayMS __unused, uint32_t *pu32DelayMS __unused)
{
return 0;
}
int wraper_set_track_mute(uint32_t hTrack __unused, bool mute __unused)
{
return 0;
}
int wraper_set_track_pre_scale(uint32_t hTrack __unused, int s32IntegerGain __unused, int s32DecimalGain __unused)
{
return 0;
}
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_get_stream_info(int hw_sync_id __unused, hal_audio_stream_info* stream_info __unused)
{
return 0;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_destroy_cast(uint32_t hCast)
{
int ret;
ret = uapi_snd_set_cast_enable(hCast, TD_FALSE);
if (ret != TD_SUCCESS) {
ALOGD("disable cast failed(0x%x)", ret);
}
ret = uapi_snd_destroy_cast(hCast);
if (ret != TD_SUCCESS) {
ALOGD("destroy cast failed(0x%x)", ret);
}
return 0;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_set_snd_mute(hal_snd_out_port out_port, uint32_t mute)
{
int ret;
uapi_snd_out_port iapi_out_port;
iapi_out_port = get_outport_type(out_port);
ret = uapi_snd_set_soft_mute(UAPI_SND_0, iapi_out_port, mute);
if (ret != 0) {
ALOGE("call UAPI_SND_SetMute failed(0x%x)\n", ret);
}
return ret;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_open_cast(hal_snd_cast_attr cast_attr, uint32_t *hCast)
{
int ret;
uapi_snd_cast_attr stCastAttr = {0};
ret = uapi_snd_get_default_cast_attr(UAPI_SND_0, &stCastAttr);
if (ret != TD_SUCCESS) {
ALOGE("call UAPI_SND_GetDefaultCastAttr failed(0x%x)", ret);
}
stCastAttr.add_mute = cast_attr.add_mute;
stCastAttr.pcm_frame_max_num = cast_attr.pcm_frame_max_num;
stCastAttr.pcm_samples = cast_attr.pcm_samples;
ret = uapi_snd_create_cast(UAPI_SND_0, &stCastAttr, hCast);
if (ret != TD_SUCCESS) {
ALOGE("call UAPI_SND_CreateCast failed(0x%x)", ret);
return ret;
}
ret = uapi_snd_set_cast_enable(*hCast, TD_TRUE);
if (ret != TD_SUCCESS) {
ALOGE("call UAPI_SND_SetCastEnable failed(0x%x)", ret);
ret = uapi_snd_destroy_cast(*hCast);
if (ret != TD_SUCCESS) {
ALOGE("call UAPI_SND_DestroyCast failed(0x%x)", ret);
}
}
return ret;
}
#endif
int wraper_close_cast(uint32_t hCast)
{
return wraper_destroy_cast(hCast);
}
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_read_cast(uint32_t hCast, uint32_t *cacheBufSize, uint8_t *cacheBuf)
{
int32_t ret;
uint32_t u32FrameBytes;
uapi_audio_frame sAoFrame = {0};
uapi_audio_frame *pstAOFrame = &sAoFrame;
while (1) {
ret = uapi_snd_acquire_cast_frame(hCast, pstAOFrame, 0);
if (ret == SOC_ERR_AO_CAST_TIMEOUT) {
usleep(CAST_SLEEP_MS);
continue;
} else if (ret != 0) {
ALOGE("%s:read failed(0x%x)", __func__, ret);
return ret;
}
u32FrameBytes = pstAOFrame->pcm_samples * BYTES_PER_SAMPLE;
if (*cacheBufSize + u32FrameBytes <= HCI_CACHE_BUFFER_SIZE) {
ret = memcpy_s(cacheBuf + *cacheBufSize, (HCI_CACHE_BUFFER_SIZE - *cacheBufSize),
pstAOFrame->pcm_buffer, u32FrameBytes);
if (ret != 0) {
ALOGE("wraper_read_cast: memcpy_s failed(0x%x)", ret);
}
*cacheBufSize += u32FrameBytes;
}
ret = uapi_snd_release_cast_frame(hCast, pstAOFrame);
if (ret != 0) {
ALOGD("%s: UAPI_SND_ReleaseCastFrame failed(0x%x)", __func__, ret);
}
break;
}
return 0;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_set_snd_all_track_mute(uint32_t mute)
{
int ret;
ret = uapi_snd_set_all_track_mute(UAPI_SND_0, mute);
if (ret != 0) {
ALOGE("call UAPI_SND_SetAllTrackMute(0x%x) failed(0x%x)", mute, ret);
}
return ret;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_set_sink_delay(uint32_t delay __unused)
{
int ret = uapi_snd_set_sink_delay(UAPI_SND_0, delay);
if (ret != TD_SUCCESS) {
ALOGE("call uapi_snd_set_sink_delay failed(0x%x)", ret);
}
return ret;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_get_sink_delay(uint32_t *delay)
{
int ret = uapi_snd_get_sink_delay(UAPI_SND_0, delay);
if (ret != TD_SUCCESS) {
ALOGE("call uapi_snd_get_sink_delay failed(0x%x)", ret);
}
return ret;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_set_cast_volume(uint32_t hCast, int32_t integer_gain, int32_t decimal_gain)
{
int32_t ret;
uapi_snd_preci_gain stPreciGain = {0};
if (hCast == INVALID_HANDLE) {
ALOGD("invalid cast handle wraper_set_cast_volume failed");
return -1;
}
stPreciGain.integer = integer_gain;
stPreciGain.decimal = decimal_gain;
ALOGD("wraper_set_cast_volume: set cast(0x%x) Vol(Int: %d, Deci: %d)",
hCast, stPreciGain.integer, stPreciGain.decimal);
ret = uapi_snd_set_cast_preci_volume(hCast, &stPreciGain);
if (ret != TD_SUCCESS) {
ALOGE("call uapi_snd_set_cast_preci_volume failed(0x%x)", ret);
}
return ret;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_set_cast_mute(uint32_t hCast, bool mute)
{
int32_t ret;
ret = uapi_snd_set_cast_mute(hCast, mute);
ALOGD("set cast: 0x%x mute: %d ret(0x%x)", hCast, mute, ret);
return ret;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_set_output_latency_mode(hal_snd_output_latency out_mode)
{
int ret;
uapi_snd_output_latency out_put_latency;
if (out_mode == HAL_SND_OUTPUTLATENCY_NORMAL) {
out_put_latency = UAPI_SND_OUTPUTLATENCY_NORMAL;
} else if (out_mode == HAL_SND_OUTPUTLATENCY_LOW) {
out_put_latency = UAPI_SND_OUTPUTLATENCY_LOW;
} else if (out_mode == HAL_SND_OUTPUTLATENCY_MAX) {
out_put_latency = UAPI_SND_OUTPUTLATENCY_MAX;
} else {
out_put_latency = UAPI_SND_OUTPUTLATENCY_NORMAL;
}
ret = uapi_snd_set_output_latency_mode(UAPI_SND_0, UAPI_SND_OUTPUTLATENCY_NORMAL);
if (ret != 0) {
ALOGE("call UAPI_SND_Open failed(0x%x)", ret);
}
return ret;
}
#endif
#if (UAPI_VERSION_CODE == UAPI_VERSION(1, 0))
int wraper_amp_init(void)
{
td_s32 ret;
ret = uapi_amp_open();
if (ret != TD_SUCCESS) {
ALOGE("%s: uapi_amp_open called failed(0x%x)", __func__, ret);
}
return ret;
}
int wraper_amp_deinit(void)
{
td_s32 ret;
ret = uapi_amp_close();
if (ret != TD_SUCCESS) {
ALOGE("%s: uapi_amp_close called failed(0x%x)", __func__, ret);
return ret;
}
return ret;
}
#endif