/* * 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 #include #include #include #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