322 lines
7.9 KiB
C
322 lines
7.9 KiB
C
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/poll.h>
|
|
#include <unistd.h>
|
|
|
|
#include "rk_defines.h"
|
|
#include "rk_debug.h"
|
|
#include "rk_mpi_aenc.h"
|
|
#include "rk_mpi_ai.h"
|
|
#include "rk_mpi_mb.h"
|
|
#include "rk_mpi_sys.h"
|
|
|
|
#define AENC_EN 1
|
|
#define AVQE_EN 1
|
|
|
|
#define AUDIO_RATE AUDIO_SAMPLE_RATE_16000
|
|
#define AUDIO_BITS AUDIO_BIT_WIDTH_16
|
|
#define AUDIO_CH_CAP 2
|
|
#define AUDIO_CH_REF 2
|
|
#define AUDIO_CH (AUDIO_CH_CAP + AUDIO_CH_REF)
|
|
#define AUDIO_CH_OUT 1
|
|
|
|
#define AUDIO_PERIOD_SZ 256
|
|
#define AUDIO_PERIOD_CNT 4
|
|
|
|
static AUDIO_DEV aiDevId = 0;
|
|
static AIO_ATTR_S aiAttr;
|
|
static AI_CHN aiChn = 0;
|
|
static AENC_CHN_ATTR_S aeAttr;
|
|
static AENC_CHN aeChn = 0;
|
|
static MPP_CHN_S aiBindAttr, aencBindAttr;
|
|
static RK_S32 aiVqeChn = 0;
|
|
static AI_VQE_CONFIG_S stAiVqeConfig, stAiVqeConfig2;
|
|
|
|
static AUDIO_SOUND_MODE_E sound_mode(int ch)
|
|
{
|
|
switch (ch)
|
|
{
|
|
case 1:
|
|
return AUDIO_SOUND_MODE_MONO;
|
|
case 2:
|
|
return AUDIO_SOUND_MODE_STEREO;
|
|
case 4:
|
|
return AUDIO_SOUND_MODE_4_CHN;
|
|
case 6:
|
|
return AUDIO_SOUND_MODE_6_CHN;
|
|
case 8:
|
|
return AUDIO_SOUND_MODE_8_CHN;
|
|
default:
|
|
return AUDIO_SOUND_MODE_BUTT;
|
|
}
|
|
}
|
|
|
|
int ai_init(void)
|
|
{
|
|
AI_CHN_PARAM_S pstParams;
|
|
RK_S32 result;
|
|
|
|
memset(&aiAttr, 0, sizeof(AIO_ATTR_S));
|
|
snprintf(aiAttr.u8CardName,
|
|
sizeof(aiAttr.u8CardName), "default");
|
|
aiAttr.soundCard.channels = AUDIO_CH;
|
|
aiAttr.soundCard.sampleRate = AUDIO_RATE;
|
|
aiAttr.soundCard.bitWidth = AUDIO_BITS;
|
|
|
|
aiAttr.enBitwidth = AUDIO_BITS;
|
|
aiAttr.enSamplerate = AUDIO_RATE;
|
|
aiAttr.enSoundmode = sound_mode(AUDIO_CH_OUT);
|
|
aiAttr.u32FrmNum = AUDIO_PERIOD_CNT;
|
|
aiAttr.u32PtNumPerFrm = 1024;//AUDIO_PERIOD_SZ;
|
|
aiAttr.u32EXFlag = 0;
|
|
aiAttr.u32ChnCnt = 4;
|
|
|
|
result = RK_MPI_AI_SetPubAttr(aiDevId, &aiAttr);
|
|
if (result != 0)
|
|
{
|
|
RK_LOGE("ai set attr fail, reason = %x", result);
|
|
return -1;
|
|
}
|
|
|
|
result = RK_MPI_AI_Enable(aiDevId);
|
|
if (result != 0)
|
|
{
|
|
RK_LOGE("ai enable fail, reason = %x", result);
|
|
return -1;
|
|
}
|
|
|
|
memset(&pstParams, 0, sizeof(AI_CHN_PARAM_S));
|
|
pstParams.enLoopbackMode = AUDIO_LOOPBACK_NONE;
|
|
pstParams.s32UsrFrmDepth = -1;
|
|
result = RK_MPI_AI_SetChnParam(aiDevId, aiChn, &pstParams);
|
|
if (result != RK_SUCCESS)
|
|
{
|
|
RK_LOGE("ai set channel params, aiChn = %d", aiChn);
|
|
goto ai_chn_err;
|
|
}
|
|
|
|
#if AVQE_EN
|
|
memset(&stAiVqeConfig, 0, sizeof(AI_VQE_CONFIG_S));
|
|
stAiVqeConfig.enCfgMode = AIO_VQE_CONFIG_LOAD_FILE;
|
|
memcpy(stAiVqeConfig.aCfgFile, "/usr/vqefiles/config_aivqe.json",
|
|
strlen("/usr/vqefiles/config_aivqe.json"));
|
|
|
|
stAiVqeConfig.s32WorkSampleRate = AUDIO_RATE;
|
|
stAiVqeConfig.s32FrameSample = AUDIO_PERIOD_SZ;
|
|
stAiVqeConfig.s64RefChannelType = 0xc; // 0b1100
|
|
stAiVqeConfig.s64RecChannelType = 0x3; // 0b0011
|
|
stAiVqeConfig.s64ChannelLayoutType = 0xf; // 0b1111
|
|
result = RK_MPI_AI_SetVqeAttr(aiDevId, aiVqeChn, 0, 0, &stAiVqeConfig);
|
|
if (result != RK_SUCCESS)
|
|
{
|
|
RK_LOGE("%s: SetVqeAttr(%d,%d) failed with %#x",
|
|
__func__, aiDevId, aiVqeChn, result);
|
|
goto vqe_err;
|
|
}
|
|
|
|
result = RK_MPI_AI_GetVqeAttr(aiDevId, aiVqeChn, &stAiVqeConfig2);
|
|
if (result != RK_SUCCESS)
|
|
{
|
|
RK_LOGE("%s: SetVqeAttr(%d,%d) failed with %#x",
|
|
__func__, aiDevId, aiChn, result);
|
|
goto vqe_err;
|
|
}
|
|
|
|
result = memcmp(&stAiVqeConfig, &stAiVqeConfig2, sizeof(AI_VQE_CONFIG_S));
|
|
if (result != RK_SUCCESS)
|
|
{
|
|
RK_LOGE("%s: set/get vqe config is different: %x", __func__, result);
|
|
goto vqe_err;
|
|
}
|
|
|
|
result = RK_MPI_AI_EnableVqe(aiDevId, aiVqeChn);
|
|
if (result != RK_SUCCESS)
|
|
{
|
|
RK_LOGE("%s: EnableVqe(%d,%d) failed with %#x",
|
|
__func__, aiDevId, aiVqeChn, result);
|
|
goto vqe_err;
|
|
}
|
|
#endif
|
|
|
|
result = RK_MPI_AI_EnableChn(aiDevId, aiChn);
|
|
if (result != 0)
|
|
{
|
|
RK_LOGE("ai enable channel fail, aiChn = %d, reason = %x", aiChn, result);
|
|
goto ai_chn_err;
|
|
}
|
|
|
|
#if AENC_EN
|
|
aeAttr.enType = RK_AUDIO_ID_PCM_ALAW;
|
|
//aeAttr.stCodecAttr.enType = RK_AUDIO_ID_PCM_ALAW;
|
|
aeAttr.stCodecAttr.u32Channels = AUDIO_CH_OUT;
|
|
aeAttr.stCodecAttr.u32SampleRate = AUDIO_RATE;
|
|
aeAttr.stCodecAttr.enBitwidth = AUDIO_BITS;
|
|
//aeAttr.stCodecAttr.pstResv = RK_NULL;
|
|
aeAttr.u32BufCount = 4;
|
|
aeAttr.u32Depth = aeAttr.u32BufCount;
|
|
|
|
result = RK_MPI_AENC_CreateChn(aeChn, &aeAttr);
|
|
if (result)
|
|
{
|
|
RK_LOGE("create aenc chn %d err:0x%x\n", aeChn, result);
|
|
goto aenc_err;
|
|
}
|
|
|
|
aiBindAttr.enModId = RK_ID_AI;
|
|
aiBindAttr.s32DevId = aiDevId;
|
|
aiBindAttr.s32ChnId = aiChn;
|
|
aencBindAttr.enModId = RK_ID_AENC;
|
|
aencBindAttr.s32DevId = aiDevId;
|
|
aencBindAttr.s32ChnId = aeChn;
|
|
|
|
result = RK_MPI_SYS_Bind(&aiBindAttr, &aencBindAttr);
|
|
if (result)
|
|
{
|
|
RK_LOGE("bind ai aenc failed:0x%x\n", result);
|
|
goto bind_err;
|
|
}
|
|
#endif
|
|
|
|
return RK_SUCCESS;
|
|
|
|
#if AENC_EN
|
|
bind_err:
|
|
RK_MPI_AENC_DestroyChn(aeChn);
|
|
aenc_err:
|
|
RK_MPI_AI_DisableChn(aiDevId, aiChn);
|
|
#endif
|
|
ai_chn_err:
|
|
#if AVQE_EN
|
|
RK_MPI_AI_DisableVqe(aiDevId, aiVqeChn);
|
|
vqe_err:
|
|
#endif
|
|
RK_MPI_AI_Disable(aiDevId);
|
|
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
int ai_fetch(int (*hook)(void *, char *, int), void *arg)
|
|
{
|
|
#if !AENC_EN
|
|
AUDIO_FRAME_S getFrame;
|
|
RK_S32 result;
|
|
|
|
result = RK_MPI_AI_GetFrame(aiDevId, aiChn, &getFrame, RK_NULL, -1);
|
|
if (result == 0)
|
|
{
|
|
void *data = RK_MPI_MB_Handle2VirAddr(getFrame.pMbBlk);
|
|
RK_LOGV("data = %p, len = %d", data, getFrame.u32Len);
|
|
if (getFrame.u32Len <= 0)
|
|
{
|
|
RK_LOGD("get ai frame end");
|
|
return 0;
|
|
}
|
|
result = (hook(arg, data, getFrame.u32Len) <= 0) ? RK_FAILURE : RK_SUCCESS;
|
|
RK_MPI_AI_ReleaseFrame(aiDevId, aiChn, &getFrame, RK_NULL);
|
|
}
|
|
#else
|
|
AUDIO_STREAM_S pstStream;
|
|
RK_S32 result;
|
|
RK_S32 eos = 0;
|
|
|
|
result = RK_MPI_AENC_GetStream(aeChn, &pstStream, -1);
|
|
if (result == RK_SUCCESS)
|
|
{
|
|
MB_BLK bBlk = pstStream.pMbBlk;
|
|
RK_VOID *pstFrame = RK_MPI_MB_Handle2VirAddr(bBlk);
|
|
RK_S32 frameSize = pstStream.u32Len;
|
|
eos = (frameSize <= 0) ? 1 : 0;
|
|
if (pstFrame)
|
|
{
|
|
RK_LOGV("get frame data = %p, size = %d", pstFrame, frameSize);
|
|
result = (hook(arg, pstFrame, frameSize) <= 0) ? RK_FAILURE : RK_SUCCESS;
|
|
RK_MPI_AENC_ReleaseStream(aeChn, &pstStream);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
int ai_deinit(void)
|
|
{
|
|
int ret = 0;
|
|
#if AENC_EN
|
|
ret = RK_MPI_SYS_UnBind(&aiBindAttr, &aencBindAttr);
|
|
if (ret)
|
|
{
|
|
RK_LOGE("ai unbind aenc failed:0x%x\n", ret);
|
|
}
|
|
#endif
|
|
|
|
ret = RK_MPI_AI_DisableChn(aiDevId, aiChn);
|
|
if (ret)
|
|
{
|
|
RK_LOGE("ai disable chn failed:0x%x\n", ret);
|
|
}
|
|
|
|
#if AVQE_EN
|
|
ret = RK_MPI_AI_DisableVqe(aiDevId, aiVqeChn);
|
|
if (ret)
|
|
{
|
|
RK_LOGE("ai disable vqe failed:0x%x\n", ret);
|
|
}
|
|
#endif
|
|
|
|
ret = RK_MPI_AI_Disable(aiDevId);
|
|
if (ret)
|
|
{
|
|
RK_LOGE("ai disable failed:0x%x\n", ret);
|
|
}
|
|
|
|
#if AENC_EN
|
|
ret = RK_MPI_AENC_DestroyChn(aeChn);
|
|
if (ret)
|
|
{
|
|
RK_LOGE("aenc destroy chn failed:0x%x\n", ret);
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef AUDIO_IN_MAIN
|
|
static int duration = 0;
|
|
static int last_ts = -1;
|
|
static int ai_save(void *arg, char *buf, int len)
|
|
{
|
|
int ret = fwrite(buf, 1, len, arg);
|
|
|
|
duration += len / sizeof(short) / AUDIO_CH_OUT / (AUDIO_RATE / 1000);
|
|
if (duration / 1000 != last_ts)
|
|
{
|
|
last_ts = duration / 1000;
|
|
RK_LOGI("duration: %.3fs %d", duration / 1000.0, len);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void main(void)
|
|
{
|
|
void *buf;
|
|
int len;
|
|
FILE *fd;
|
|
fd = fopen("/tmp/ch0.pcm", "wb+");
|
|
|
|
RK_MPI_SYS_Init();
|
|
|
|
ai_init();
|
|
while (duration < 10000)
|
|
ai_fetch(ai_save, fd);
|
|
ai_deinit();
|
|
|
|
RK_MPI_SYS_Exit();
|
|
|
|
fclose(fd);
|
|
}
|
|
#endif
|
|
|