海思平台播放AAC音频

来源:互联网 发布:知乎 蓝洞 韩国 编辑:程序博客网 时间:2024/05/16 04:47

利用海思sdk的sample修改了一个播AAC的小程序

代码

主程序voice_player.c:

/******************************************************************************  A simple program of Hisilicon HI3516 audio input/output/encoder/decoder implementation.  Copyright (C), 2010-2011, Hisilicon Tech. Co., Ltd. ******************************************************************************    Modification:  2011-2 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 "hi_comm_vb.h"#include "audio_aac_adp.h"#define TEST_AIO_ID        0#define AIO_WORK_MODE      AIO_MODE_I2S_MASTERstatic PAYLOAD_TYPE_E gs_enPayloadType = PT_AAC;static AAC_TYPE_E gs_enAacType = AAC_TYPE_AACLC;static AAC_BPS_E gs_enAacBps  = AAC_BPS_24K;static HI_BOOL gs_bUserGetMode = HI_FALSE;//static HI_BOOL gs_bMicIn = HI_FALSE;//static HI_U32 g_InnerCodecInput = 1; /*0-micin 1-linein 2-micind 3-lineind*///static HI_U32 g_InnerCodecOutput = 0; /*0-lineout 1-leftd 2-rightd*/#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_AAC == enType)  return "aac";    else return "data";}/******************************************************************************* function : Open Aenc File******************************************************************************/static FILE * SAMPLE_AUDIO_OpenAencFile(AENC_CHN AeChn, PAYLOAD_TYPE_E enType){    FILE *pfd;    HI_CHAR aszFileName[128];    /* create file for save stream*/    snprintf(aszFileName, sizeof(aszFileName), "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(char *filename){    FILE *pfd;    pfd = fopen(filename, "rb");    if (NULL == pfd)    {        printf("%s: open file %s failed\n", __FUNCTION__, filename);        return NULL;    }    printf("open stream file:\"%s\" for adec ok\n", filename);    return pfd;}/******************************************************************************* function : Start Aenc******************************************************************************/HI_S32 SAMPLE_AUDIO_StartAenc(HI_S32 s32AencChnCnt, AIO_ATTR_S *pstAioAttr, PAYLOAD_TYPE_E enType){    AENC_CHN AeChn;    HI_S32 s32Ret, i;    AENC_CHN_ATTR_S stAencAttr;    AENC_ATTR_AAC_S stAencAac;    /* set AENC chn attr */    stAencAttr.enType = enType;    stAencAttr.u32BufSize = 30;stAencAttr.u32PtNumPerFrm = pstAioAttr->u32PtNumPerFrm;    if (PT_AAC == stAencAttr.enType)    {        stAencAttr.pValue = &stAencAac;        stAencAac.enAACType = gs_enAacType;        stAencAac.enBitRate = gs_enAacBps;        stAencAac.enBitWidth = AUDIO_BIT_WIDTH_16;        stAencAac.enSmpRate = pstAioAttr->enSamplerate;        stAencAac.enSoundMode = pstAioAttr->enSoundmode;        stAencAac.enTransType = AAC_TRANS_TYPE_ADTS;        stAencAac.s16BandWidth = 0;    }    else    {        printf("%s: invalid aenc payload type:%d\n", __FUNCTION__, stAencAttr.enType);        return HI_FAILURE;    }    for (i=0; i<s32AencChnCnt; i++)    {        AeChn = i;        /* create aenc chn*/        s32Ret = HI_MPI_AENC_CreateChn(AeChn, &stAencAttr);        if (s32Ret != HI_SUCCESS)        {            printf("%s: HI_MPI_AENC_CreateChn(%d) failed with %#x!\n", __FUNCTION__,                   AeChn, s32Ret);            return HI_FAILURE;        }    }    return HI_SUCCESS;}/******************************************************************************* function : Start Adec******************************************************************************/HI_S32 SAMPLE_AUDIO_StartAdec(ADEC_CHN AdChn, PAYLOAD_TYPE_E enType){    HI_S32 s32Ret;    ADEC_CHN_ATTR_S stAdecAttr;    ADEC_ATTR_AAC_S stAdecAac;    stAdecAttr.enType = enType;    stAdecAttr.u32BufSize = 20;    stAdecAttr.enMode = ADEC_MODE_STREAM;/* propose use pack mode in your app */if (PT_AAC == stAdecAttr.enType)    {        stAdecAttr.pValue = &stAdecAac;        stAdecAttr.enMode = ADEC_MODE_STREAM;   /* aac should be stream mode */        stAdecAac.enTransType = AAC_TRANS_TYPE_ADTS;    }    else    {        printf("%s: invalid aenc payload type:%d\n", __FUNCTION__, stAdecAttr.enType);        return HI_FAILURE;    }    /* create adec chn*/    s32Ret = HI_MPI_ADEC_CreateChn(AdChn, &stAdecAttr);    if (s32Ret)    {        printf("%s: HI_MPI_ADEC_CreateChn(%d) failed with %#x!\n", __FUNCTION__,\               AdChn,s32Ret);        return s32Ret;    }    return 0;}/******************************************************************************* function : file -> ADec -> Ao******************************************************************************/HI_S32 SAMPLE_AUDIO_AdecAo(char *filename, AIO_ATTR_S *pstAioAttr){    HI_S32      s32Ret;#ifdef AO_DEV    AUDIO_DEV AoDev = AO_DEV;#elseAUDIO_DEV AoDev = TEST_AIO_ID;#endif    AO_CHN      AoChn = 0;    ADEC_CHN    AdChn = 0;HI_S32 s32AoChnCnt;    FILE        *pfd = NULL;    if (NULL == pstAioAttr)    {        printf("%s: input piont is invalid!\n", __FUNCTION__);        return HI_FAILURE;    }    s32Ret = SAMPLE_COMM_AUDIO_CfgAcodec(pstAioAttr);    if (HI_SUCCESS != s32Ret)    {        SAMPLE_DBG(s32Ret);        goto ADECAO_ERR3;    }    s32Ret = SAMPLE_AUDIO_StartAdec(AdChn, gs_enPayloadType);    if (s32Ret != HI_SUCCESS)    {        SAMPLE_DBG(s32Ret);        goto ADECAO_ERR3;    }s32AoChnCnt = pstAioAttr->u32ChnCnt;    s32Ret = SAMPLE_COMM_AUDIO_StartAo(AoDev, s32AoChnCnt, pstAioAttr, AUDIO_SAMPLE_RATE_BUTT, HI_FALSE, NULL, 0);    if (s32Ret != HI_SUCCESS)    {        SAMPLE_DBG(s32Ret);        goto ADECAO_ERR2;    }    s32Ret = SAMPLE_COMM_AUDIO_AoBindAdec(AoDev, AoChn, AdChn);    if (s32Ret != HI_SUCCESS)    {        SAMPLE_DBG(s32Ret);        goto ADECAO_ERR1;    }    pfd = SAMPLE_AUDIO_OpenAdecFile(filename);    if (!pfd)    {        SAMPLE_DBG(HI_FAILURE);        goto ADECAO_ERR0;    }    s32Ret = SAMPLE_COMM_AUDIO_CreatTrdFileAdec(AdChn, pfd);    if (s32Ret != HI_SUCCESS)    {        SAMPLE_DBG(s32Ret);        goto ADECAO_ERR0;    }    printf("bind adec:%d to ao(%d,%d) ok \n", AdChn, AoDev, AoChn);    //SAMPLE_COMM_AUDIO_DestoryTrdFileAdec(AdChn);ADECAO_ERR0:    s32Ret |= SAMPLE_COMM_AUDIO_AoUnbindAdec(AoDev, AoChn, AdChn);ADECAO_ERR1:    s32Ret |= SAMPLE_COMM_AUDIO_StopAo(AoDev, s32AoChnCnt, HI_FALSE, HI_FALSE);ADECAO_ERR2:    s32Ret |= SAMPLE_COMM_AUDIO_StopAdec(AdChn);ADECAO_ERR3:    return s32Ret;}/******************************************************************************* function : to process abnormal case******************************************************************************/void SAMPLE_AUDIO_HandleSig(HI_S32 signo){    if (SIGINT == signo || SIGTSTP == 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[]){    char ch;    HI_S32 s32Ret= HI_SUCCESS;    AIO_ATTR_S stAioAttr;    /* init stAio. all of cases will use it */    memset(&stAioAttr, 0, sizeof(AIO_ATTR_S));    stAioAttr.enBitwidth = AUDIO_BIT_WIDTH_16;    stAioAttr.enWorkmode = AIO_WORK_MODE;    stAioAttr.enSoundmode = AUDIO_SOUND_MODE_MONO;    stAioAttr.u32EXFlag = 0;    stAioAttr.u32FrmNum = 30;    stAioAttr.u32ChnCnt = 1;    #ifdef HI_ACODEC_TYPE_TLV320AIC31    stAioAttr.u32ClkSel = 1;    #else    stAioAttr.u32ClkSel = 0;    #endifstAioAttr.enSamplerate = AUDIO_SAMPLE_RATE_8000;stAioAttr.u32PtNumPerFrm = (AAC_TYPE_AACLC == gs_enAacType) ? 1024 : 2048;    //signal(SIGINT, SAMPLE_AUDIO_HandleSig);    //signal(SIGTERM, SAMPLE_AUDIO_HandleSig);    s32Ret = SAMPLE_COMM_SYS_Init();    if (HI_SUCCESS != s32Ret)    {        printf("%s: system init failed with %d!\n", __FUNCTION__, s32Ret);        return HI_FAILURE;    }    /* register aac encoder and decoder */    HI_MPI_ADEC_AacInit();    s32Ret = SAMPLE_AUDIO_AdecAo(argv[1],&stAioAttr);/* read audio stream from file,decode and send AO*/    if (s32Ret != HI_SUCCESS)    {    }    SAMPLE_COMM_SYS_Exit();    return HI_SUCCESS;}
什么标注了几个关键的点。

sample_comm_audio.c部分代码:

/******************************************************************************* function : Create the thread to get stream from file and send to adec******************************************************************************/HI_S32 SAMPLE_COMM_AUDIO_CreatTrdFileAdec(ADEC_CHN AdChn, FILE *pAdcFd){    SAMPLE_ADEC_S *pstAdec = NULL;    if (NULL == pAdcFd)    {        return HI_FAILURE;    }    pstAdec = &gs_stSampleAdec[AdChn];    pstAdec->AdChn = AdChn;    pstAdec->pfd = pAdcFd;    pstAdec->bStart = HI_TRUE;    //pthread_create(&pstAdec->stAdPid, 0, SAMPLE_COMM_AUDIO_AdecProc, pstAdec);    SAMPLE_COMM_AUDIO_AdecProc(pstAdec);    return HI_SUCCESS;}
/******************************************************************************* function : get stream from file, and send it  to Adec******************************************************************************/void *SAMPLE_COMM_AUDIO_AdecProc(SAMPLE_ADEC_S *pstAdec){    HI_S32 s32Ret;    AUDIO_STREAM_S stAudioStream;    HI_U32 u32Len = 2048;    HI_U32 u32ReadLen;    HI_S32 s32AdecChn;    HI_U8 *pu8AudioStream = NULL;    SAMPLE_ADEC_S *pstAdecCtl = (SAMPLE_ADEC_S *)pstAdec;    AO_CHN_STATE_S pstStatus;    FILE *pfd = pstAdecCtl->pfd;    s32AdecChn = pstAdecCtl->AdChn;    pu8AudioStream = (HI_U8*)malloc(sizeof(HI_U8)*MAX_AUDIO_STREAM_LEN);    if (NULL == pu8AudioStream)    {        printf("%s: malloc failed!\n", __FUNCTION__);        return NULL;    }    while (HI_TRUE == pstAdecCtl->bStart)    {        /* read from file */        stAudioStream.pStream = pu8AudioStream;        u32ReadLen = fread(stAudioStream.pStream, 1, u32Len, pfd);        if (u32ReadLen <= 0)        {            /*            s32Ret = HI_MPI_ADEC_SendEndOfStream(s32AdecChn, HI_FALSE);            if (HI_SUCCESS != s32Ret)            {                printf("%s: HI_MPI_ADEC_SendEndOfStream failed!\n", __FUNCTION__);            }            fseek(pfd, 0, SEEK_SET);            */            printf("u32ReadLen <= 0 break! s32Ret:%d \n",s32Ret);            break;        }        /* here only demo adec streaming sending mode, but pack sending mode is commended */        stAudioStream.u32Len = u32ReadLen;        s32Ret = HI_MPI_ADEC_SendStream(s32AdecChn, &stAudioStream, HI_TRUE);        if(HI_SUCCESS != s32Ret)        {            printf("%s: HI_MPI_ADEC_SendStream(%d) failed with %#x!\n",\                   __FUNCTION__, s32AdecChn, s32Ret);            //break;        }        usleep(1000*10);    }    while (HI_TRUE == pstAdecCtl->bStart)    {        s32Ret = HI_MPI_AO_QueryChnStat(0, 0,&pstStatus);        //printf("pstStatus.u32ChnBusyNum: %d\n",pstStatus.u32ChnBusyNum);        if(pstStatus.u32ChnBusyNum < 1)        {            s32Ret = HI_MPI_ADEC_SendEndOfStream(s32AdecChn, HI_FALSE);            if (HI_SUCCESS != s32Ret)            {                printf("%s: HI_MPI_ADEC_SendEndOfStream failed!\n", __FUNCTION__);            }            break;        }        sleep(1);    }    free(pu8AudioStream);    pu8AudioStream = NULL;    fclose(pfd);    pstAdecCtl->bStart = HI_FALSE;    return NULL;}
注意播放时要查询AO 通道中当的音频数据态,等到缓存为空时再停止播放,不然只能播一部分,不能播完。

编译

上makefile

include config.mkLOCAL_SRC_CFILES := \voice_player.c \src/audio_aac_adp.c \src/sample_comm_audio.c \src/sample_comm_sys.cLOCAL_MODULE := voice_playerLOCAL_CFLAGS := -D__LINUX__PREFIX := arm-hisiv300-linux-LOCAL_SHARED_LIBRARIES := pthread \LOCAL_C_INCLUDES :=./include \./ \LOCAL_LDFLAGS := lib/libaacdec.so \     lib/libmpi.so \     lib/libisp.so \             lib/libive.so\             lib/libVoiceEngine.so \             lib/libupvqe.so \             lib/libdnvqe.so \             lib/lib_hidefog.so \             lib/libaacenc.so \include exec_rules.mk
只看makefile的话应该就能看出我的目录结构吧!

水一波@_@~






原创粉丝点击