sdk-hwV1.3/external/eyesee-mpp/middleware/sun8iw21/media/audio/ans/WebRtcAns.c

251 lines
8.0 KiB
C
Raw Normal View History

2024-05-07 10:09:20 +00:00
#define LOG_NDEBUG 0
#define LOG_TAG "WebRtcAns"
#include <utils/plat_log.h>
#include <stdlib.h>
#include <string.h>
#include <ans_lib.h>
#include "WebRtcAns.h"
extern void aw_WebRtcSpl_AnalysisQMF(const int16_t* in_data,
int16_t* low_band,
int16_t* high_band,
int32_t* filter_state1,
int32_t* filter_state2);
extern void aw_WebRtcSpl_SynthesisQMF(const int16_t* low_band,
const int16_t* high_band,
int16_t* out_data,
int32_t* filter_state1,
int32_t* filter_state2);
WebRtcAnsContext* ConstructWebRtcAnsContext()
{
WebRtcAnsContext *pCtx = (WebRtcAnsContext*)malloc(sizeof(WebRtcAnsContext));
if(NULL == pCtx)
{
aloge("fatal error! malloc fail");
}
memset(pCtx, 0, sizeof(*pCtx));
return pCtx;
}
void DestructWebRtcAnsContext(WebRtcAnsContext *pCtx)
{
int ret;
if(pCtx->ans_int != NULL)
{
ret = WebRtcNs_Free(pCtx->ans_int);
if(0 == ret)
{
//alogd("aec_ans_released");
pCtx->ans_int = NULL;
}
else
{
aloge("fatal error! aec_ans_release_failed");
}
}
if(pCtx->tmpBuf_ans != NULL)
{
free(pCtx->tmpBuf_ans);
pCtx->tmpBuf_ans = NULL;
}
if(NULL != pCtx->out_buff_ans)
{
free(pCtx->out_buff_ans);
pCtx->out_buff_ans = NULL;
}
if(NULL != pCtx->in_buff_ans)
{
free(pCtx->in_buff_ans);
pCtx->in_buff_ans = NULL;
}
free(pCtx);
}
/**
implement of AnsProcessFuncType.
*/
int WebRtcAnsProcess(void *cookie, AUDIO_FRAME_S *pFrm, const AIO_ATTR_S *pAttr, BOOL bSuspendAns)
{
int rc;
int ret;
if(pAttr->enSoundmode != AUDIO_SOUND_MODE_MONO)
{
aloge("fatal error! webRtcAns only can process one channel, not support soundmode[%d]", pAttr->enSoundmode);
return 0;
}
WebRtcAnsContext *pCtx = (WebRtcAnsContext*)cookie;
if(NULL == pCtx->ans_int)
{
ret = WebRtcNs_Create(&pCtx->ans_int); // instance
if(NULL == pCtx->ans_int || 0 != ret)
{
aloge("fatal error! aec_ans_instance_create_fail:%d", ret);
return -1;
}
ret = WebRtcNs_Init(pCtx->ans_int, 32000); //pAttr->enSamplerate
if(0 != ret)
{
aloge("fatal error! aec_ans_init_failed:%d",ret);
}
ret = WebRtcNs_set_policy(pCtx->ans_int, pAttr->ai_ans_mode);
if(0 != ret)
{
aloge("fatal error! aec_ans_cfg_failed");
}
memset(pCtx->filter_state1,0,sizeof(pCtx->filter_state1));
memset(pCtx->filter_state12,0,sizeof(pCtx->filter_state12));
memset(pCtx->Synthesis_state1,0,sizeof(pCtx->Synthesis_state1));
memset(pCtx->Synthesis_state12,0,sizeof(pCtx->Synthesis_state12));
}
if(NULL == pCtx->in_buff_ans)
{
pCtx->in_buff_ans = (short *)malloc(pFrm->mLen*2);
if(NULL == pCtx->in_buff_ans)
{
aloge("fatal error! malloc fail:%d", pFrm->mLen*2);
}
pCtx->in_buff_len_ans = pFrm->mLen*2;
pCtx->in_buff_data_remain_len_ans = 0;
}
else
{
if(pCtx->in_buff_len_ans != pFrm->mLen*2)
{
aloge("fatal error! why ans in buf len wrong?[%d != %d*2]", pCtx->in_buff_len_ans, pFrm->mLen);
}
}
if(NULL == pCtx->out_buff_ans)
{
pCtx->out_buff_ans = (short *)malloc(pFrm->mLen*2);
if(NULL == pCtx->out_buff_ans)
{
aloge("fatal error! malloc fail:%d", pFrm->mLen*2);
}
pCtx->out_buff_len_ans = pFrm->mLen*2;
pCtx->out_buff_data_remain_len_ans = 0;
}
else
{
if(pCtx->out_buff_len_ans != pFrm->mLen*2)
{
aloge("fatal error! why ans out buf len wrong?[%d != %d*2]", pCtx->out_buff_len_ans, pFrm->mLen);
}
}
if(NULL == pCtx->tmpBuf_ans)
{
pCtx->tmpBuf_ans = (short*)malloc(pFrm->mLen*2);
if(NULL == pCtx->tmpBuf_ans)
{
aloge("fatal error! malloc fail:%d", pFrm->mLen*2);
}
pCtx->tmpBufLen_ans = pFrm->mLen*2;
}
else
{
if(pCtx->tmpBufLen_ans != pFrm->mLen*2)
{
aloge("fatal error! why ans out tmp buf len wrong?[%d != %d*2]", pCtx->tmpBufLen_ans, pFrm->mLen);
}
}
//memset(pCtx->tmpBuf_ans, 0, pCtx->tmpBufLen_ans);
// move data in near buffer and reference buffer to internal buffer for conjunction with remaining data for last process.
if(pCtx->in_buff_data_remain_len_ans + pFrm->mLen <= pCtx->in_buff_len_ans)
{
memcpy((char*)pCtx->in_buff_ans + pCtx->in_buff_data_remain_len_ans, (char*)pFrm->mpAddr, pFrm->mLen);
pCtx->in_buff_data_remain_len_ans += pFrm->mLen;
}
else
{
aloge("fatal error! in_buff_over_flow:%d-%d-%d", pCtx->in_buff_data_remain_len_ans, pCtx->in_buff_len_ans, pFrm->mLen);
}
int frm_size = 320; // 160 samples as one unit processed by aec library, we use two units.
short tmp_near_buffer[320]; //for in_buff_ans
short tmp_ans_shInL[160] = {0};
short tmp_ans_shInH[160] = {0};
short tmp_ans_shOutL[160] = {0};
short tmp_ans_shOutH[160] = {0};
short *near_frm_ptr = (short *)pCtx->in_buff_ans; //for in_buff_ans
short *processed_frm_ptr = (short *)pCtx->tmpBuf_ans; //for tmpBuf_ans, out_buff_data
int left = pCtx->in_buff_data_remain_len_ans / sizeof(short);
// start to process
while(left >= frm_size)
{
if(FALSE == bSuspendAns)
{
memcpy((char *)tmp_near_buffer, (char *)near_frm_ptr, frm_size*sizeof(short));
aw_WebRtcSpl_AnalysisQMF(tmp_near_buffer, tmp_ans_shInL, tmp_ans_shInH, pCtx->filter_state1, pCtx->filter_state12);
if (0 == WebRtcNs_Process(pCtx->ans_int, tmp_ans_shInL, tmp_ans_shInH, tmp_ans_shOutL, tmp_ans_shOutH))
{
aw_WebRtcSpl_SynthesisQMF(tmp_ans_shOutL, tmp_ans_shOutH, processed_frm_ptr, pCtx->Synthesis_state1, pCtx->Synthesis_state12);
}
}
else
{
memcpy((char*)processed_frm_ptr, (char *)near_frm_ptr, frm_size*sizeof(short));
}
near_frm_ptr += frm_size;
processed_frm_ptr += frm_size;
left -= frm_size;
pCtx->in_buff_data_remain_len_ans -= frm_size*sizeof(short);
}
// move remaining data in internal buffer to the beginning of the buffer
if(left > 0)
{
memmove((char*)pCtx->in_buff_ans, (char*)near_frm_ptr, pCtx->in_buff_data_remain_len_ans);
}
unsigned int out_offset = (unsigned int)processed_frm_ptr - (unsigned int)pCtx->tmpBuf_ans;
if(out_offset + pCtx->out_buff_data_remain_len_ans > pCtx->out_buff_len_ans)
{
aloge("fatal error! ans_out_buff_over_flow:%d-%d-%d", pCtx->out_buff_data_remain_len_ans, pCtx->out_buff_len_ans, out_offset);
}
else
{
memcpy((char *)pCtx->out_buff_ans + pCtx->out_buff_data_remain_len_ans, (char *)pCtx->tmpBuf_ans, out_offset);
pCtx->out_buff_data_remain_len_ans += out_offset;
}
// fetch one valid output frame from output internal buffer, the length of valid frame must equal to chunsize.
if(pCtx->out_buff_data_remain_len_ans >= pFrm->mLen)
{
memcpy((char *)pFrm->mpAddr, (char *)pCtx->out_buff_ans, pFrm->mLen);
pCtx->out_buff_data_remain_len_ans -= pFrm->mLen;
if(pFrm->mLen != pAttr->mPtNumPerFrm*sizeof(short))
{
aloge("fatal error! ans_frameLen wrong:%d != %d", pAttr->mPtNumPerFrm*sizeof(short), pFrm->mLen);
}
if(pCtx->out_buff_data_remain_len_ans > pFrm->mLen)
{
aloge("fatal error! ans_out_buff_data too long:%d-%d", pFrm->mLen, pCtx->out_buff_data_remain_len_ans);
}
memmove((char *)pCtx->out_buff_ans, ((char *)pCtx->out_buff_ans + pFrm->mLen), pCtx->out_buff_data_remain_len_ans);
rc = 0;
}
else
{
rc = 1;
}
return rc;
}