1.使用固件自带的sample_ai_aenc程序,sample_ai_aenc -d default:CARD=hw:0,0 -w 16bit -R 16000 -r 16000 -C 2 -c 2 -e g711a -o /data/直接录制音频,生成的音频文件在ffmpeg杂音很大。
2.#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include "audio.h"
#include "sample_comm.h"
#include <stdbool.h>
typedef struct _rkMpiCtx {
SAMPLE_AI_CTX_S ai;
SAMPLE_AENC_CTX_S aenc;
} SAMPLE_MPI_CTX_S;
static bool quit = false;
#define MP3_PROFILE_LOW 1
typedef struct FreqIdx_ {
RK_S32 u32SmpRate;
RK_U8 u8FreqIdx;
} FreqIdx;
FreqIdx FreqIdxTbl[13] = {{96000, 0}, {88200, 1}, {64000, 2}, {48000, 3}, {44100, 4},
{32000, 5}, {24000, 6}, {22050, 7}, {16000, 8}, {12000, 9},
{11025, 10}, {8000, 11}, {7350, 12}};
static void GetHeader(RK_U8 *pu8Hdr, RK_S32 u32SmpRate, RK_U8 u8Channel,
RK_U32 u32DataLen) {
RK_U8 u8FreqIdx = 0;
for (int i = 0; i < 13; i++) {
if (u32SmpRate == FreqIdxTbl.u32SmpRate) {
u8FreqIdx = FreqIdxTbl.u8FreqIdx;
break;
}
}
RK_U32 u32PacketLen = u32DataLen + 7;
pu8Hdr[0] = 0xFF;
pu8Hdr[1] = 0xF1;
pu8Hdr[2] = ((MP3_PROFILE_LOW) << 6) + (u8FreqIdx << 2) + (u8Channel >> 2);
pu8Hdr[3] = (((u8Channel & 3) << 6) + (u32PacketLen >> 11));
pu8Hdr[4] = ((u32PacketLen & 0x7FF) >> 3);
pu8Hdr[5] = (((u32PacketLen & 7) << 5) + 0x1F);
pu8Hdr[6] = 0xFC;
}
static void *aenc_get_stream(void *pArgs) {
SAMPLE_AENC_CTX_S *ctx = (SAMPLE_AENC_CTX_S *)(pArgs);
RK_S32 s32Ret = RK_FAILURE;
FILE *fp = RK_NULL;
void *pData = RK_NULL;
RK_S32 loopCount = 0;
RK_U8 header[7];
fp = fopen("audio.test", "wb");
if (fp == RK_NULL) {
printf("can't open audio.test file !\n");
quit = true;
return RK_NULL;
}
while (!quit) {
s32Ret = SAMPLE_COMM_AENC_GetStream(ctx, &pData);
if (s32Ret == RK_SUCCESS) {
// exit when complete
if (ctx->s32loopCount > 0) {
if (loopCount >= ctx->s32loopCount) {
SAMPLE_COMM_AENC_ReleaseStream(ctx);
printf("SAMPLE_COMM_AENC_ReleaseStream \n");
quit = true;
break;
}
}
if (fp) {
if (code_type == RK_AUDIO_ID_MP3) {
GetHeader(header, ctx->stChnAttr.stCodecAttr.u32SampleRate,
ctx->stChnAttr.stCodecAttr.u32Channels,
ctx->stFrame.u32Len);
fwrite(header, 1, 7, fp);
}
fwrite(pData, 1, ctx->stFrame.u32Len, fp);
fflush(fp);
}
SAMPLE_COMM_AENC_ReleaseStream(ctx);
loopCount++;
}
usleep(1000);
}
if (fp)
fclose(fp);
return NULL;
}
int audio_init(void)
{
SAMPLE_MPI_CTX_S *ctx;
MPP_CHN_S stSrcChn, stDestChn;
RK_S32 s32DeviceChannel = 2;
RK_S32 s32DeviceSampleRate = 16000;
AUDIO_BIT_WIDTH_E bitWidth = AUDIO_BIT_WIDTH_16;
RK_S32 s32SampleRate = 8000;
AUDIO_SOUND_MODE_E soundMode = AUDIO_SOUND_MODE_MONO;
RK_S32 s32ChnCnt = 2;
RK_S32 s32PeriodCount = 4;
RK_S32 s32PeriodSize = 1024;
RK_S32 s32loopCnt = -1;
RK_U8 pCardName[] = "hw:0,0";
RK_CODEC_ID_E code_type = RK_AUDIO_ID_PCM_ALAW;
//RK_CHAR *pOutPath = NULL;
ctx = (SAMPLE_MPI_CTX_S *)(malloc(sizeof(SAMPLE_MPI_CTX_S)));
memset(ctx, 0, sizeof(SAMPLE_MPI_CTX_S));
// Init AI[0]
ctx->ai.s32DevId = 0;
ctx->ai.s32ChnId = 0;
ctx->ai.stAiAttr.soundCard.channels = s32DeviceChannel;
ctx->ai.stAiAttr.soundCard.sampleRate = s32DeviceSampleRate;
ctx->ai.stAiAttr.soundCard.bitWidth = bitWidth;
ctx->ai.stAiAttr.enBitwidth = bitWidth;
ctx->ai.stAiAttr.enSamplerate = (AUDIO_SAMPLE_RATE_E)s32SampleRate;
ctx->ai.stAiAttr.enSoundmode = soundMode;
ctx->ai.stAiAttr.u32FrmNum = s32PeriodCount;
ctx->ai.stAiAttr.u32PtNumPerFrm = s32PeriodSize;
ctx->ai.stAiAttr.u32EXFlag = 0;
ctx->ai.stAiAttr.u32ChnCnt = s32ChnCnt;
if (pCardName) {
strcpy((char *)ctx->ai.stAiAttr.u8CardName, pCardName);
}
SAMPLE_COMM_AI_CreateChn(&ctx->ai);
// Init AENC[0]
ctx->aenc.s32ChnId = 0;
ctx->aenc.s32loopCount = s32loopCnt;
ctx->aenc.stChnAttr.enType = code_type;
ctx->aenc.stChnAttr.stCodecAttr.u32Channels = s32ChnCnt;
ctx->aenc.stChnAttr.stCodecAttr.u32SampleRate = s32SampleRate;
ctx->aenc.stChnAttr.stCodecAttr.enBitwidth = bitWidth;
ctx->aenc.stChnAttr.u32BufCount = 4;
//ctx->aenc.dstFilePath = pOutPath;
SAMPLE_COMM_AENC_CreateChn(&ctx->aenc);
// Bind AI[0] and AENC[0]
stSrcChn.enModId = RK_ID_AI;
stSrcChn.s32DevId = ctx->ai.s32DevId;
stSrcChn.s32ChnId = ctx->ai.s32ChnId;
stDestChn.enModId = RK_ID_AENC;
stDestChn.s32DevId = 0;
stDestChn.s32ChnId = ctx->aenc.s32ChnId;
SAMPLE_COMM_Bind(&stSrcChn, &stDestChn);
pthread_t getStreamThread;
pthread_create(&getStreamThread, NULL, aenc_get_stream, (void *)(&ctx->aenc));
printf("%s initial finish\n", __func__);
while (!quit) {
usleep(500000);
}
printf("%s exit!\n", __func__);
pthread_join(getStreamThread, NULL);
// UnBind AI[0] and AENC[0]
stSrcChn.enModId = RK_ID_AI;
stSrcChn.s32DevId = ctx->ai.s32DevId;
stSrcChn.s32ChnId = ctx->ai.s32ChnId;
stDestChn.enModId = RK_ID_AENC;
stDestChn.s32DevId = 0;
stDestChn.s32ChnId = ctx->aenc.s32ChnId;
SAMPLE_COMM_UnBind(&stSrcChn, &stDestChn);
// Destroy AENC[0]
SAMPLE_COMM_AENC_DestroyChn(&ctx->aenc);
// Destroy AI[0]
SAMPLE_COMM_AI_DestroyChn(&ctx->ai);
//RK_MPI_SYS_Exit();
return 0;
}
使用该demo,保存的音频流是错误的。想咨询是否哪里参数配置有问题?
luckfox pico ultra w使用sample_ai_aenc直接录制音频再用ffmpeg播放有很大杂音
测试了一下使用arecord -f S16_LE -c 2 -r 16000 -D hw:0 -d 30 test.wav录制,再用aplay -Dhw:0 test.wav播放是可以的。
但是使用rk_mpi_ai_test --sound_card_name=hw:0,0 --device_rate=16000 --device_ch=2 --out_rate=16000 --out_ch=2 --output=/tmp
用rk_mpi_ao_test -i /tmp/2.pcm --sound_card_name=hw:0,0 --device_ch=2 --device_rate=16000 --input_rate=16000 --input_ch=2就听起来都是杂音。
使用的buildroot系统。
但是使用rk_mpi_ai_test --sound_card_name=hw:0,0 --device_rate=16000 --device_ch=2 --out_rate=16000 --out_ch=2 --output=/tmp
用rk_mpi_ao_test -i /tmp/2.pcm --sound_card_name=hw:0,0 --device_ch=2 --device_rate=16000 --input_rate=16000 --input_ch=2就听起来都是杂音。
使用的buildroot系统。
您好,出现杂音有可能是调用aenc时出现了问题,RV1106 在音频上并没有硬件加速的IP核基本都是使用CPU进行软件编码或解码,如果rkmpi效果不佳选择其他工具在效率上时差不多的,我们在音频上主要使用的是ffmpeg,rkmpi上的测试比较少,主要还是使用rk_mpi_amix_test来设置控制器