系列文章目录
海思3518ev200学习记录(1)- 根据用户手册烧录系统镜像
海思3518ev200学习记录(2) - 交叉编译官方webRTC
海思3518ev200学习记录(3) - 编译 amazon-kinesis webrtc嵌入式实现
海思3518ev200学习记录(4) - 基于海思源码分段录制音频文件
前言
前一篇文章已经测试并编译成功了,但是遇到一个新的问题,因为之前大佬留下的坑哈,代码中实现的仅仅是只读,也就是开了俩线程在读取磁盘中文件,但是文件咋生成呢?怎么才能实时获取呢。作为java工程师,突然让搞这个也是小白,功夫不负有心人,咱也是能看懂一部分代码的,从海思源码中抽取了音频文件生成。
开始
找到开发商给点海思板子代码示例,在目录/mmp/sample/audio
中找到sample_audio.c
文件,这就是开发商给的音频测试源码,如果你正常make编译成功,并放到板子上运行你就能找到生成的音频文件,但还是无法满足我们目前的需求,因为我们是一帧一帧的循环读取的,源码中是直接不停追加的想办法搞定它。
那么下面我们开搞。
编译
海思的源码
/******************************************************************************
A simple program of Hisilicon mpp audio input/output/encoder/decoder implementation.
Copyright (C), 2010-2021, Hisilicon Tech. Co., Ltd.
******************************************************************************
Modification: 2013-7 Created
******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include <signal.h>
#include "sample_comm.h"
#include "acodec.h"
#include "tlv320aic31.h"
static PAYLOAD_TYPE_E gs_enPayloadType = PT_ADPCMA;
//static HI_BOOL gs_bMicIn = HI_FALSE;
static HI_BOOL gs_bAioReSample = HI_FALSE;
static HI_BOOL gs_bUserGetMode = HI_FALSE;
static HI_BOOL gs_bAoVolumeCtrl = HI_TRUE;
static AUDIO_SAMPLE_RATE_E enInSampleRate = AUDIO_SAMPLE_RATE_BUTT;
static AUDIO_SAMPLE_RATE_E enOutSampleRate = AUDIO_SAMPLE_RATE_BUTT;
static HI_U32 u32AencPtNumPerFrm = 0;
/* 0: close, 1: open*/
static HI_U32 u32AiVqeType = 1;
/* 0: close, 1: open*/
static HI_U32 u32AoVqeType = 1;
#define SAMPLE_DBG(s32Ret)\
do{\
printf("s32Ret=%#x,fuc:%s,line:%d\n", s32Ret, __FUNCTION__, __LINE__);\
}while(0)
/******************************************************************************
* function : PT Number to String
******************************************************************************/
static char* SAMPLE_AUDIO_Pt2Str(PAYLOAD_TYPE_E enType)
{
if (PT_G711A == enType)
{
return "g711a";
}
else if (PT_G711U == enType)
{
return "g711u";
}
else if (PT_ADPCMA == enType)
{
return "adpcm";
}
else if (PT_G726 == enType)
{
return "g726";
}
else if (PT_LPCM == enType)
{
return "pcm";
}
else
{
return "data";
}
}
/******************************************************************************
* function : Open Aenc File
******************************************************************************/
static FILE * SAMPLE_AUDIO_OpenAencFile(AENC_CHN AeChn, PAYLOAD_TYPE_E enType)
{
FILE* pfd;
HI_CHAR aszFileName[FILE_NAME_LEN];
/* create file for save stream*/
snprintf(aszFileName, FILE_NAME_LEN, "audio_chn%d.%s", AeChn, SAMPLE_AUDIO_Pt2Str(enType));
pfd = fopen(aszFileName, "w+");
if (NULL == pfd)
{
printf("%s: open file %s failed\n", __FUNCTION__, aszFileName);
return NULL;
}
printf("open stream file:\"%s\" for aenc ok\n", aszFileName);
return pfd;
}
/******************************************************************************
* function : Open Adec File
******************************************************************************/
static FILE *SAMPLE_AUDIO_OpenAdecFile(ADEC_CHN AdChn, PAYLOAD_TYPE_E enType)
{
FILE* pfd;
HI_CHAR aszFileName[FILE_NAME_LEN];
/* create file for save stream*/
snprintf(aszFileName, FILE_NAME_LEN ,"audio_chn%d.%s", AdChn, SAMPLE_AUDIO_Pt2Str(enType));
pfd = fopen(aszFileName, "rb");
if (NULL == pfd)
{
printf("%s: open file %s failed\n", __FUNCTION__, aszFileName);
return NULL;
}
printf("open stream file:\"%s\" for adec ok\n", aszFileName);
return pfd;
}
/******************************************************************************
* function : file -> Adec -> Ao
******************************************************************************/
HI_S32 SAMPLE_AUDIO_AdecAo(HI_VOID)
{
HI_S32 s32Ret;
AUDIO_DEV AoDev = SAMPLE_AUDIO_AO_DEV;
AO_CHN AoChn = 0;
ADEC_CHN AdChn = 0;
HI_S32 s32AoChnCnt;
FILE* pfd = NULL;
AIO_ATTR_S stAioAttr;
#ifdef HI_ACODEC_TYPE_TLV320AIC31
stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_8000;
stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
stAioAttr.enWorkmode = AIO_MODE_I2S_MASTER;
stAioAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;
stAioAttr.u32EXFlag = 0;
stAioAttr.u32FrmNum = 30;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
stAioAttr.u32ChnCnt = 1;
stAioAttr.u32ClkSel = 1;
#else
stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_8000;
stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
stAioAttr.enWorkmode = AIO_MODE_I2S_MASTER;
stAioAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;
stAioAttr.u32EXFlag = 0;
stAioAttr.u32FrmNum = 30;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
stAioAttr.u32ChnCnt = 1;
stAioAttr.u32ClkSel = 0;
#endif
gs_bAioReSample = HI_FALSE;
enInSampleRate = AUDIO_SAMPLE_RATE_BUTT;
enOutSampleRate = AUDIO_SAMPLE_RATE_BUTT;
s32Ret = SAMPLE_COMM_AUDIO_CfgAcodec(&stAioAttr);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_StartAdec(AdChn, gs_enPayloadType);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32AoChnCnt = stAioAttr.u32ChnCnt;
s32Ret = SAMPLE_COMM_AUDIO_StartAo(AoDev, s32AoChnCnt, &stAioAttr, enInSampleRate, gs_bAioReSample, NULL, 0);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_AoBindAdec(AoDev, AoChn, AdChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
pfd = SAMPLE_AUDIO_OpenAdecFile(AdChn, gs_enPayloadType);
if (!pfd)
{
SAMPLE_DBG(HI_FAILURE);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_CreatTrdFileAdec(AdChn, pfd);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
printf("bind adec:%d to ao(%d,%d) ok \n", AdChn, AoDev, AoChn);
printf("\nplease press twice ENTER to exit this sample\n");
getchar();
getchar();
s32Ret = SAMPLE_COMM_AUDIO_DestoryTrdFileAdec(AdChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_StopAdec(AdChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_StopAo(AoDev, s32AoChnCnt, gs_bAioReSample, HI_FALSE);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_AoUnbindAdec(AoDev, AoChn, AdChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
return HI_SUCCESS;
}
/******************************************************************************
* function : Ai -> Aenc -> file
* -> Adec -> Ao
******************************************************************************/
HI_S32 SAMPLE_AUDIO_AiAenc(HI_VOID)
{
HI_S32 i, s32Ret;
AUDIO_DEV AiDev = SAMPLE_AUDIO_AI_DEV;
AI_CHN AiChn;
AUDIO_DEV AoDev = SAMPLE_AUDIO_AO_DEV;
AO_CHN AoChn = 0;
ADEC_CHN AdChn = 0;
HI_S32 s32AiChnCnt;
HI_S32 s32AoChnCnt;
HI_S32 s32AencChnCnt;
AENC_CHN AeChn;
HI_BOOL bSendAdec = HI_TRUE;
FILE *pfd = NULL;
AIO_ATTR_S stAioAttr;
#ifdef HI_ACODEC_TYPE_TLV320AIC31
stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_8000;
stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
stAioAttr.enWorkmode = AIO_MODE_I2S_MASTER;
stAioAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;
stAioAttr.u32EXFlag = 0;
stAioAttr.u32FrmNum = 30;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
stAioAttr.u32ChnCnt = 1;
stAioAttr.u32ClkSel = 1;
#else
stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_8000;
stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
stAioAttr.enWorkmode = AIO_MODE_I2S_MASTER;
stAioAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;
stAioAttr.u32EXFlag = 0;
stAioAttr.u32FrmNum = 30;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
stAioAttr.u32ChnCnt = 1;
stAioAttr.u32ClkSel = 0;
#endif
gs_bAioReSample = HI_FALSE;
enInSampleRate = AUDIO_SAMPLE_RATE_BUTT;
enOutSampleRate = AUDIO_SAMPLE_RATE_BUTT;
u32AencPtNumPerFrm = stAioAttr.u32PtNumPerFrm;
/********************************************
step 1: config audio codec
********************************************/
s32Ret = SAMPLE_COMM_AUDIO_CfgAcodec(&stAioAttr);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/********************************************
step 2: start Ai
********************************************/
s32AiChnCnt = stAioAttr.u32ChnCnt;
s32Ret = SAMPLE_COMM_AUDIO_StartAi(AiDev, s32AiChnCnt, &stAioAttr, enOutSampleRate, gs_bAioReSample, NULL, 0);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/********************************************
step 3: start Aenc
********************************************/
s32AencChnCnt = 1;
s32Ret = SAMPLE_COMM_AUDIO_StartAenc(s32AencChnCnt, u32AencPtNumPerFrm, gs_enPayloadType);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/********************************************
step 4: Aenc bind Ai Chn
********************************************/
for (i=0; i<s32AencChnCnt; i++)
{
AeChn = i;
AiChn = i;
if (HI_TRUE == gs_bUserGetMode)
{
s32Ret = SAMPLE_COMM_AUDIO_CreatTrdAiAenc(AiDev, AiChn, AeChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
else
{
s32Ret = SAMPLE_COMM_AUDIO_AencBindAi(AiDev, AiChn, AeChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return s32Ret;
}
}
printf("Ai(%d,%d) bind to AencChn:%d ok!\n",AiDev , AiChn, AeChn);
}
/********************************************
step 5: start Adec & Ao. ( if you want )
********************************************/
if (HI_TRUE == bSendAdec)
{
s32Ret = SAMPLE_COMM_AUDIO_StartAdec(AdChn, gs_enPayloadType);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32AoChnCnt = stAioAttr.u32ChnCnt;
s32Ret = SAMPLE_COMM_AUDIO_StartAo(AoDev, s32AoChnCnt, &stAioAttr, enInSampleRate, gs_bAioReSample, NULL , 0);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
pfd = SAMPLE_AUDIO_OpenAencFile(AdChn, gs_enPayloadType);
if (!pfd)
{
SAMPLE_DBG(HI_FAILURE);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_CreatTrdAencAdec(AeChn, AdChn, pfd);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_AoBindAdec(AoDev, AoChn, AdChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
printf("bind adec:%d to ao(%d,%d) ok \n", AdChn, AoDev, AoChn);
}
printf("\nplease press twice ENTER to exit this sample\n");
getchar();
getchar();
/********************************************
step 6: exit the process
********************************************/
if (HI_TRUE == bSendAdec)
{
s32Ret = SAMPLE_COMM_AUDIO_DestoryTrdAencAdec(AdChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_StopAo(AoDev, s32AoChnCnt, gs_bAioReSample, HI_FALSE);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_StopAdec(AdChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_AoUnbindAdec(AoDev, AoChn, AdChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
for (i=0; i<s32AencChnCnt; i++)
{
AeChn = i;
AiChn = i;
if (HI_TRUE == gs_bUserGetMode)
{
s32Ret = SAMPLE_COMM_AUDIO_DestoryTrdAi(AiDev, AiChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
else
{
s32Ret = SAMPLE_COMM_AUDIO_AencUnbindAi(AiDev, AiChn, AeChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
}
s32Ret = SAMPLE_COMM_AUDIO_StopAenc(s32AencChnCnt);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_StopAi(AiDev, s32AiChnCnt, gs_bAioReSample, HI_FALSE);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
return HI_SUCCESS;
}
/******************************************************************************
* function : Ai -> Ao(with fade in/out and volume adjust)
******************************************************************************/
HI_S32 SAMPLE_AUDIO_AiAo(HI_VOID)
{
HI_S32 s32Ret;
HI_S32 s32AiChnCnt;
HI_S32 s32AoChnCnt;
AUDIO_DEV AiDev = SAMPLE_AUDIO_AI_DEV;
AI_CHN AiChn = 0;
AUDIO_DEV AoDev = SAMPLE_AUDIO_AO_DEV;
AO_CHN AoChn = 0;
AIO_ATTR_S stAioAttr;
#ifdef HI_ACODEC_TYPE_TLV320AIC31
stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_8000;
stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
stAioAttr.enWorkmode = AIO_MODE_I2S_MASTER;
stAioAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;
stAioAttr.u32EXFlag = 0;
stAioAttr.u32FrmNum = 30;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
stAioAttr.u32ChnCnt = 1;
stAioAttr.u32ClkSel = 1;
#else // inner acodec
stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_8000;
stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
stAioAttr.enWorkmode = AIO_MODE_I2S_MASTER;
stAioAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;
stAioAttr.u32EXFlag = 0;
stAioAttr.u32FrmNum = 30;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
stAioAttr.u32ChnCnt = 1;
stAioAttr.u32ClkSel = 0;
#endif
/* config ao resample attr if needed */
if (HI_TRUE == gs_bAioReSample)
{
stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_32000;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM * 4;
/* ai 32k -> 8k */
enOutSampleRate = AUDIO_SAMPLE_RATE_8000;
/* ao 8k -> 32k */
enInSampleRate = AUDIO_SAMPLE_RATE_8000;
}
else
{
enInSampleRate = AUDIO_SAMPLE_RATE_BUTT;
enOutSampleRate = AUDIO_SAMPLE_RATE_BUTT;
}
/* resample and anr should be user get mode */
gs_bUserGetMode = (HI_TRUE == gs_bAioReSample) ? HI_TRUE : HI_FALSE;
/* config audio codec */
s32Ret = SAMPLE_COMM_AUDIO_CfgAcodec(&stAioAttr);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/* enable AI channle */
s32AiChnCnt = stAioAttr.u32ChnCnt;
s32Ret = SAMPLE_COMM_AUDIO_StartAi(AiDev, s32AiChnCnt, &stAioAttr, enOutSampleRate, gs_bAioReSample, NULL, 0);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/* enable AO channle */
s32AoChnCnt = stAioAttr.u32ChnCnt;
s32Ret = SAMPLE_COMM_AUDIO_StartAo(AoDev, s32AoChnCnt, &stAioAttr, enInSampleRate, gs_bAioReSample, NULL, 0);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/* bind AI to AO channle */
if (HI_TRUE == gs_bUserGetMode)
{
s32Ret = SAMPLE_COMM_AUDIO_CreatTrdAiAo(AiDev, AiChn, AoDev, AoChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
else
{
s32Ret = SAMPLE_COMM_AUDIO_AoBindAi(AiDev, AiChn, AoDev, AoChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
printf("ai(%d,%d) bind to ao(%d,%d) ok\n", AiDev, AiChn, AoDev, AoChn);
if(HI_TRUE == gs_bAoVolumeCtrl)
{
s32Ret = SAMPLE_COMM_AUDIO_CreatTrdAoVolCtrl(AoDev);
if(s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
printf("\nplease press twice ENTER to exit this sample\n");
getchar();
getchar();
if(HI_TRUE == gs_bAoVolumeCtrl)
{
s32Ret = SAMPLE_COMM_AUDIO_DestoryTrdAoVolCtrl(AoDev);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
if (HI_TRUE == gs_bUserGetMode)
{
s32Ret = SAMPLE_COMM_AUDIO_DestoryTrdAi(AiDev, AiChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
else
{
s32Ret = SAMPLE_COMM_AUDIO_AoUnbindAi(AiDev, AiChn, AoDev, AoChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
s32Ret = SAMPLE_COMM_AUDIO_StopAi(AiDev, s32AiChnCnt, gs_bAioReSample, HI_FALSE);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_StopAo(AoDev, s32AoChnCnt, gs_bAioReSample, HI_FALSE);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
return HI_SUCCESS;
}
/******************************************************************************
* function : Ai -> Ao
******************************************************************************/
HI_S32 SAMPLE_AUDIO_AiVqeProcessAo(HI_VOID)
{
HI_S32 i, s32Ret;
AUDIO_DEV AiDev = SAMPLE_AUDIO_AI_DEV;
AUDIO_DEV AoDev = SAMPLE_AUDIO_AO_DEV;
HI_S32 s32AiChnCnt;
HI_S32 s32AoChnCnt;
AIO_ATTR_S stAioAttr;
AI_VQE_CONFIG_S stAiVqeAttr;
HI_VOID *pAiVqeAttr = NULL;
AO_VQE_CONFIG_S stAoVqeAttr;
HI_VOID *pAoVqeAttr = NULL;
#ifdef HI_ACODEC_TYPE_TLV320AIC31
stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_8000;
stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
stAioAttr.enWorkmode = AIO_MODE_I2S_MASTER;
stAioAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;
stAioAttr.u32EXFlag = 0;
stAioAttr.u32FrmNum = 30;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
stAioAttr.u32ChnCnt = 1;
stAioAttr.u32ClkSel = 1;
#else
stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_8000;
stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
stAioAttr.enWorkmode = AIO_MODE_I2S_MASTER;
stAioAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;
stAioAttr.u32EXFlag = 0;
stAioAttr.u32FrmNum = 30;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
stAioAttr.u32ChnCnt = 1;
stAioAttr.u32ClkSel = 0;
#endif
gs_bAioReSample = HI_FALSE;
enInSampleRate = AUDIO_SAMPLE_RATE_BUTT;
enOutSampleRate = AUDIO_SAMPLE_RATE_BUTT;
if (1 == u32AiVqeType)
{
stAiVqeAttr.s32WorkSampleRate = AUDIO_SAMPLE_RATE_8000;
stAiVqeAttr.s32FrameSample = SAMPLE_AUDIO_PTNUMPERFRM;
stAiVqeAttr.enWorkstate = VQE_WORKSTATE_COMMON;
stAiVqeAttr.bAecOpen = HI_TRUE;
stAiVqeAttr.stAecCfg.bUsrMode = HI_FALSE;
stAiVqeAttr.stAecCfg.s8CngMode = 0;
stAiVqeAttr.bAgcOpen = HI_TRUE;
stAiVqeAttr.stAgcCfg.bUsrMode = HI_FALSE;
stAiVqeAttr.bAnrOpen = HI_TRUE;
stAiVqeAttr.stAnrCfg.bUsrMode = HI_FALSE;
stAiVqeAttr.bHpfOpen = HI_TRUE;
stAiVqeAttr.stHpfCfg.bUsrMode = HI_TRUE;
stAiVqeAttr.stHpfCfg.enHpfFreq = AUDIO_HPF_FREQ_150;
stAiVqeAttr.bRnrOpen = HI_FALSE;
stAiVqeAttr.bEqOpen = HI_FALSE;
stAiVqeAttr.bHdrOpen = HI_FALSE;
pAiVqeAttr = (HI_VOID *)&stAiVqeAttr;
}
else
{
pAiVqeAttr = HI_NULL;
}
if (1 == u32AoVqeType)
{
memset(&stAoVqeAttr, 0, sizeof(AO_VQE_CONFIG_S));
stAoVqeAttr.s32WorkSampleRate = AUDIO_SAMPLE_RATE_8000;
stAoVqeAttr.s32FrameSample = SAMPLE_AUDIO_PTNUMPERFRM;
stAoVqeAttr.enWorkstate = VQE_WORKSTATE_COMMON;
stAoVqeAttr.stAgcCfg.bUsrMode = HI_FALSE;
stAoVqeAttr.stAnrCfg.bUsrMode = HI_FALSE;
stAoVqeAttr.stHpfCfg.bUsrMode = HI_TRUE;
stAoVqeAttr.stHpfCfg.enHpfFreq = AUDIO_HPF_FREQ_150;
stAoVqeAttr.bAgcOpen = HI_TRUE;
stAoVqeAttr.bAnrOpen = HI_TRUE;
stAoVqeAttr.bEqOpen = HI_TRUE;
stAoVqeAttr.bHpfOpen = HI_TRUE;
pAoVqeAttr = (HI_VOID *)&stAoVqeAttr;
}
/********************************************
step 1: config audio codec
********************************************/
s32Ret = SAMPLE_COMM_AUDIO_CfgAcodec(&stAioAttr);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/********************************************
step 2: start Ai
********************************************/
s32AiChnCnt = stAioAttr.u32ChnCnt;
s32Ret = SAMPLE_COMM_AUDIO_StartAi(AiDev, s32AiChnCnt, &stAioAttr, enOutSampleRate, gs_bAioReSample, pAiVqeAttr, u32AiVqeType);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/********************************************
step 3: start Ao
********************************************/
s32AoChnCnt = stAioAttr.u32ChnCnt;
s32Ret = SAMPLE_COMM_AUDIO_StartAo(AoDev, s32AoChnCnt, &stAioAttr, enInSampleRate, gs_bAioReSample, pAoVqeAttr, u32AoVqeType);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/********************************************
step 4: Ao bind Ai Chn
********************************************/
for (i=0; i<s32AiChnCnt; i++)
{
s32Ret = SAMPLE_COMM_AUDIO_CreatTrdAiAo(AiDev, i, AoDev, i);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
printf("bind ai(%d,%d) to ao(%d,%d) ok \n", AiDev, i, AoDev, i);
}
printf("\nplease press twice ENTER to exit this sample\n");
getchar();
getchar();
/********************************************
step 6: exit the process
********************************************/
for (i=0; i<s32AiChnCnt; i++)
{
s32Ret = SAMPLE_COMM_AUDIO_DestoryTrdAi(AiDev, i);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
s32Ret = SAMPLE_COMM_AUDIO_StopAi(AiDev, s32AiChnCnt, gs_bAioReSample, HI_TRUE);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_AUDIO_StopAo(AoDev, s32AoChnCnt, gs_bAioReSample, HI_TRUE);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
return HI_SUCCESS;
}
HI_VOID SAMPLE_AUDIO_Usage(HI_VOID)
{
printf("\n\n/************************************/\n");
printf("please choose the case which you want to run:\n");
printf("\t0: start AI to AO loop\n");
printf("\t1: send audio frame to AENC channel from AI, save them\n");
printf("\t2: read audio stream from file, decode and send AO\n");
printf("\t3: start AI(AEC/ANR/ALC process), then send to AO\n");
printf("\tq: quit whole audio sample\n\n");
printf("sample command:");
}
/******************************************************************************
* function : to process abnormal case
******************************************************************************/
void SAMPLE_AUDIO_HandleSig(HI_S32 signo)
{
if (SIGINT == signo || SIGTERM == signo)
{
SAMPLE_COMM_AUDIO_DestoryAllTrd();
SAMPLE_COMM_SYS_Exit();
printf("\033[0;31mprogram exit abnormally!\033[0;39m\n");
}
exit(0);
}
/******************************************************************************
* function : main
******************************************************************************/
HI_S32 main(int argc, char *argv[])
{
HI_S32 s32Ret = HI_SUCCESS;
HI_CHAR ch;
HI_BOOL bExit = HI_FALSE;
VB_CONF_S stVbConf;
signal(SIGINT, SAMPLE_AUDIO_HandleSig);
signal(SIGTERM, SAMPLE_AUDIO_HandleSig);
memset(&stVbConf, 0, sizeof(VB_CONF_S));
s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf);
if (HI_SUCCESS != s32Ret)
{
printf("%s: system init failed with %d!\n", __FUNCTION__, s32Ret);
return HI_FAILURE;
}
/******************************************
1 choose the case
******************************************/
while (1)
{
SAMPLE_AUDIO_Usage();
ch = (char)getchar();
getchar();
switch (ch)
{
case '0':
{
SAMPLE_AUDIO_AiAo();
break;
}
case '1':
{
SAMPLE_AUDIO_AiAenc();
break;
}
case '2':
{
SAMPLE_AUDIO_AdecAo();
break;
}
case '3':
{
SAMPLE_AUDIO_AiVqeProcessAo();
break;
}
case 'q':
case 'Q':
{
bExit = HI_TRUE;
break;
}
default :
{
printf("input invaild! please try again.\n");
break;
}
}
if (bExit)
{
break;
}
}
SAMPLE_COMM_SYS_Exit();
return s32Ret;
}
修改后的
/******************************************************************************
A simple program of Hisilicon mpp audio input/output/encoder/decoder implementation.
Copyright (C), 2010-2021, Hisilicon Tech. Co., Ltd.
******************************************************************************
Modification: 2013-7 Created
******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include <signal.h>
#include "sample_comm.h"
#include "acodec.h"
#include "tlv320aic31.h"
static PAYLOAD_TYPE_E gs_enPayloadType = PT_ADPCMA;
//static HI_BOOL gs_bMicIn = HI_FALSE;
static HI_BOOL gs_bAioReSample = HI_FALSE;
static HI_BOOL gs_bUserGetMode = HI_FALSE;
static AUDIO_SAMPLE_RATE_E enInSampleRate = AUDIO_SAMPLE_RATE_BUTT;
static AUDIO_SAMPLE_RATE_E enOutSampleRate = AUDIO_SAMPLE_RATE_BUTT;
static HI_U32 u32AencPtNumPerFrm = 0;
#define SAMPLE_DBG(s32Ret)\
do{\
printf("s32Ret=%#x,fuc:%s,line:%d\n", s32Ret, __FUNCTION__, __LINE__);\
}while(0)
/******************************************************************************
* function : Open Aenc File
******************************************************************************/
static FILE * SAMPLE_AUDIO_OpenAencFile(AENC_CHN AeChn, PAYLOAD_TYPE_E enType)
{
FILE* pfd;
HI_CHAR aszFileName[FILE_NAME_LEN];
/* create file for save stream*/
snprintf(aszFileName, FILE_NAME_LEN, "/mnt/pcms/sample-%03d.%s", AeChn, "pcma");
pfd = fopen(aszFileName, "w+");
if (NULL == pfd)
{
printf("%s: open file %s failed\n", __FUNCTION__, aszFileName);
return NULL;
}
printf("open stream file:\"%s\" for aenc ok\n", aszFileName);
return pfd;
}
/******************************************************************************
* function : Ai -> Aenc -> file
* -> Adec -> Ao
* 音频处理主要方法
******************************************************************************/
HI_S32 SAMPLE_AUDIO_AiAenc(HI_VOID)
{
HI_S32 i, s32Ret;
AUDIO_DEV AiDev = SAMPLE_AUDIO_AI_DEV;
AI_CHN AiChn;
AUDIO_DEV AoDev = SAMPLE_AUDIO_AO_DEV;
AO_CHN AoChn = 0;
ADEC_CHN AdChn = 0;
HI_S32 s32AiChnCnt;
HI_S32 s32AoChnCnt;
HI_S32 s32AencChnCnt;
AENC_CHN AeChn;
FILE *pfd = NULL;
HI_BOOL bSendAdec = HI_TRUE;
AIO_ATTR_S stAioAttr;
#ifdef HI_ACODEC_TYPE_TLV320AIC31
stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_8000;
stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
stAioAttr.enWorkmode = AIO_MODE_I2S_MASTER;
stAioAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;
stAioAttr.u32EXFlag = 0;
stAioAttr.u32FrmNum = 30;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
stAioAttr.u32ChnCnt = 1;
stAioAttr.u32ClkSel = 1;
#else
stAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_8000;
stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;
stAioAttr.enWorkmode = AIO_MODE_I2S_MASTER;
stAioAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;
stAioAttr.u32EXFlag = 0;
stAioAttr.u32FrmNum = 30;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
stAioAttr.u32ChnCnt = 1;
stAioAttr.u32ClkSel = 0;
#endif
gs_bAioReSample = HI_FALSE;
enInSampleRate = AUDIO_SAMPLE_RATE_BUTT;
enOutSampleRate = AUDIO_SAMPLE_RATE_BUTT;
u32AencPtNumPerFrm = stAioAttr.u32PtNumPerFrm;
/********************************************
step 1: config audio codec
********************************************/
s32Ret = SAMPLE_COMM_AUDIO_CfgAcodec(&stAioAttr);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/********************************************
step 2: start Ai
********************************************/
s32AiChnCnt = stAioAttr.u32ChnCnt;
s32Ret = SAMPLE_COMM_AUDIO_StartAi(AiDev, s32AiChnCnt, &stAioAttr, enOutSampleRate, gs_bAioReSample, NULL, 0);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/********************************************
step 3: start Aenc
********************************************/
s32AencChnCnt = 1;
// 示例\u通信\u音频\u开始
s32Ret = SAMPLE_COMM_AUDIO_StartAenc(s32AencChnCnt, u32AencPtNumPerFrm, gs_enPayloadType);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
/********************************************
step 4: Aenc bind Ai Chn
********************************************/
for (i=0; i<s32AencChnCnt; i++)
{
AeChn = i;
AiChn = i;
if (HI_TRUE == gs_bUserGetMode)
{
//示例通信音频创建
s32Ret = SAMPLE_COMM_AUDIO_CreatTrdAiAenc(AiDev, AiChn, AeChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
}
else
{ //示例通信音频
s32Ret = SAMPLE_COMM_AUDIO_AencBindAi(AiDev, AiChn, AeChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return s32Ret;
}
}
printf("Ai(%d,%d) bind to AencChn:%d ok!\n",AiDev , AiChn, AeChn);
}
/********************************************
step 5: start Adec & Ao. ( if you want )
********************************************/
if (HI_TRUE == bSendAdec)
{
//示例通信音频开始时间
s32Ret = SAMPLE_COMM_AUDIO_StartAdec(AdChn, gs_enPayloadType);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
pfd = SAMPLE_AUDIO_OpenAencFile(AdChn, PT_LPCM);
if (!pfd)
{
SAMPLE_DBG(HI_FAILURE);
return HI_FAILURE;
}
s32AoChnCnt = stAioAttr.u32ChnCnt;
//示例\u通信\u音频\u StartAo
s32Ret = SAMPLE_COMM_AUDIO_StartAo(AoDev, s32AoChnCnt, &stAioAttr, enInSampleRate, gs_bAioReSample, NULL , 0);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
//示例通信音频创建Trd Aenc Adec
//s32Ret = SAMPLE_COMM_AUDIO_CreatTrdAencAdec(AeChn, AdChn, pfd);
s32Ret = fs_haisi_audio_file(AeChn,AdChn,pfd);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
//通信音频AoBindAdec示例
s32Ret = SAMPLE_COMM_AUDIO_AoBindAdec(AoDev, AoChn, AdChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_DBG(s32Ret);
return HI_FAILURE;
}
printf("bind adec:%d to ao(%d,%d) ok \n", AdChn, AoDev, AoChn);
}
printf("\nplease press twice ENTER to exit this sample\n");
getchar();
getchar();
return HI_SUCCESS;
}
typedef struct tagSAMPLE_AENC_S
{
HI_BOOL bStart;
pthread_t stAencPid;
HI_S32 AeChn;
HI_S32 AdChn;
FILE *pfd;
HI_BOOL bSendAdChn;
} SAMPLE_AENC_S;
static SAMPLE_AENC_S gs_stSampleAenc[AENC_MAX_CHN_NUM];
HI_S32 fs_haisi_audio_file(AENC_CHN AeChn, ADEC_CHN AdChn,FILE *pAecFd){
HI_S32 s32Ret;
SAMPLE_AENC_S *pstAenc = NULL;
if (NULL == pAecFd)
{
return HI_FAILURE;
}
pstAenc = &gs_stSampleAenc[AeChn];
pstAenc->AeChn = AeChn;
pstAenc->AdChn = AdChn;
pstAenc->bSendAdChn = HI_TRUE;
pstAenc->pfd = pAecFd;
pstAenc->bStart = HI_TRUE;
// pthread_create(&pstAenc->stAencPid, 0, SAMPLE_COMM_AUDIO_AencProc, pstAenc);
HI_S32 AencFd;
SAMPLE_AENC_S *pstAencCtl = pstAenc;
AUDIO_STREAM_S stStream;
fd_set read_fds;
struct timeval TimeoutVal;
FD_ZERO(&read_fds);
AencFd = HI_MPI_AENC_GetFd(pstAencCtl->AeChn);
FD_SET(AencFd, &read_fds);
while (pstAencCtl->bStart)
{
TimeoutVal.tv_sec = 1;
TimeoutVal.tv_usec = 0;
FD_ZERO(&read_fds);
FD_SET(AencFd,&read_fds);
s32Ret = select(AencFd+1, &read_fds, NULL, NULL, &TimeoutVal);
if (s32Ret < 0)
{
break;
}
else if (0 == s32Ret)
{
printf("%s: get aenc stream select time out\n", __FUNCTION__);
break;
}
if (FD_ISSET(AencFd, &read_fds))
{
/* get stream from aenc chn */
s32Ret = HI_MPI_AENC_GetStream(pstAencCtl->AeChn, &stStream, HI_FALSE);
if (HI_SUCCESS != s32Ret )
{
printf("%s: HI_MPI_AENC_GetStream(%d), failed with %#x!\n",\
__FUNCTION__, pstAencCtl->AeChn, s32Ret);
pstAencCtl->bStart = HI_FALSE;
return NULL;
}
printf("fs____: %d \n",stStream.u32Len);
pstAencCtl->pfd = SAMPLE_AUDIO_OpenAencFile(AdChn++, PT_LPCM);
fwrite(stStream.pStream,1,stStream.u32Len, pstAencCtl->pfd);
fflush(pstAencCtl->pfd);
/* finally you must release the stream */
s32Ret = HI_MPI_AENC_ReleaseStream(pstAencCtl->AeChn, &stStream);
if (HI_SUCCESS != s32Ret )
{
printf("%s: HI_MPI_AENC_ReleaseStream(%d), failed with......................... %#x!\n",\
__FUNCTION__, pstAencCtl->AeChn, s32Ret);
pstAencCtl->bStart = HI_FALSE;
return NULL;
}
}
printf("trhsy___ : %d \n",pstAencCtl->pfd);
}
fclose(pstAencCtl->pfd);
pstAencCtl->bStart = HI_FALSE;
return HI_SUCCESS;
}
/******************************************************************************
* function : to process abnormal case
******************************************************************************/
void SAMPLE_AUDIO_HandleSig(HI_S32 signo)
{
if (SIGINT == signo || SIGTERM == signo)
{
SAMPLE_COMM_AUDIO_DestoryAllTrd();
SAMPLE_COMM_SYS_Exit();
printf("\033[0;31mprogram exit abnormally!\033[0;39m\n");
}
exit(0);
}
/******************************************************************************
* function : main
******************************************************************************/
HI_S32 main(int argc, char *argv[])
{
HI_S32 s32Ret = HI_SUCCESS;
VB_CONF_S stVbConf;
signal(SIGINT, SAMPLE_AUDIO_HandleSig);
signal(SIGTERM, SAMPLE_AUDIO_HandleSig);
memset(&stVbConf, 0, sizeof(VB_CONF_S));
//初始化
s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf);
if (HI_SUCCESS != s32Ret)
{
printf("system init failed with %d!\n", s32Ret);
return HI_FAILURE;
}
//std::thread([]{
SAMPLE_AUDIO_AiAenc();
//}).detach();
return s32Ret;
}
好吧我删除了一部分没有用的,我认为没有用的,反正我没有用到,主要方法在我自定义的函数fs_haisi_audio_file
方法中,就是把源码中录音并发送到喇叭的部分做了调整,并且做了分段。
测试
放到板子总运行说明分段成功
并且文件真是存在
结束
目前就先这样吧,下一期准备把这部分继承到webrtc中,一边录音并生成文件,一边读取并发送到远程端。
我们下期见