AI_CHN_ATTR_S ai_attr;
ai_attr.pcAudioNode = pDeviceName;
ai_attr.enSampleFormat = RK_SAMPLE_FMT_S16;
ai_attr.u32NbSamples = u32FrameCnt;
ai_attr.u32SampleRate = u32SampleRate;
ai_attr.u32Channels = u32ChnCnt;
ai_attr.enAiLayout = AI_LAYOUT_NORMAL;
音频输入属性结构体
-
pcAudioNode//音频设备节点路径
-
enSampleFormat
-
采样格式
-
typedef enum rkSample_Format_E { RK_SAMPLE_FMT_NONE = -1, RK_SAMPLE_FMT_U8, RK_SAMPLE_FMT_S16, RK_SAMPLE_FMT_S32, RK_SAMPLE_FMT_FLT, RK_SAMPLE_FMT_U8P, RK_SAMPLE_FMT_S16P, RK_SAMPLE_FMT_S32P, RK_SAMPLE_FMT_FLTP, RK_SAMPLE_FMT_G711A, RK_SAMPLE_FMT_G711U, RK_SAMPLE_FMT_NB } Sample_Format_E;
-
不以P为结尾的都是interleaved结构,以P为结尾的是planar结构
-
Planar模式是FFmpeg内部存储模式,我们实际使用的音频文件都是Packed模式的。
-
AAC解码输出的数据为浮点型的 RK_SAMPLE_FMT_FLTP格式
-
MP3解码输出的数据为 RK_SAMPLE_FMT_S16P格式(使用的mp3文件为16位深)
-
-
u32NbSamples
- 每帧的采样点个数
- 通常一帧是按1024个采样点
-
u32SampleRate
- 采样率
- 就是每秒对声音进行采集的次数,同样也是所得的数字信号的每秒样本数;44,100 Hz - 音频 CD, 也常用于 MPEG-1 音频(VCD, SVCD, MP3)所用采样率
-
u32Channels
- 通道数
- 单通道、双声道、四声道、5.1声道
-
enAiLayout
- 输入布局类型
通过RK_MPI_AI_SetChnAttr设置音频输入通道属性 ,然后RK_MPI_AI_EnableChn打开通道0
pthread_create创建线程去获取数据流并保存
接着通过RK_MPI_AI_StartStream启动音频流
流程:文章来源:https://www.toymoban.com/news/detail-436150.html
- 设置音频输入通道属性
- 打开通道
- 启动音频流
- 创建线程去获取数据流并保存
获取数据流线程中通过从指定通道中获取数据 然后fwrite往输出音频文件中写数据,最后关闭文件文章来源地址https://www.toymoban.com/news/detail-436150.html
#include <assert.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "rkmedia_api.h"
static bool quit = false;
static void sigterm_handler(int sig) {
fprintf(stderr, "signal %d\n", sig);
quit = true;
}
static void *GetMediaBuffer(void *path) {
char *save_path = (char *)path;
printf("#Start %s thread, arg:%s\n", __func__, save_path);
FILE *save_file = fopen(save_path, "w");
if (!save_file)
printf("ERROR: Open %s failed!\n", save_path);
MEDIA_BUFFER mb = NULL;
int cnt = 0;
while (!quit) {
mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_AI, 0, -1);
if (!mb) {
printf("RK_MPI_SYS_GetMediaBuffer get null buffer!\n");
break;
}
printf("#%d Get Frame:ptr:%p, size:%zu, mode:%d, channel:%d, "
"timestamp:%lld\n",
cnt++, RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb),
RK_MPI_MB_GetModeID(mb), RK_MPI_MB_GetChannelID(mb),
RK_MPI_MB_GetTimestamp(mb));
if (save_file)
fwrite(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), save_file);
RK_MPI_MB_ReleaseBuffer(mb);
}
if (save_file)
fclose(save_file);
return NULL;
}
int main(int argc, char *argv[]) {
RK_U32 u32SampleRate = 44100;
RK_U32 u32ChnCnt = 1;
RK_U32 u32FrameCnt = 1024;
RK_S32 s32Volume = 100;
// default:CARD=rockchiprk809co
RK_CHAR *pDeviceName = "default";
RK_CHAR *pOutPath = "/mnt/nfs/ai.pcm";
int c;
int ret = 0;
printf("#Device: %s\n", pDeviceName);
printf("#SampleRate: %u\n", u32SampleRate);
printf("#Channel Count: %u\n", u32ChnCnt);
printf("#Frame Count: %u\n", u32FrameCnt);
printf("#Volume: %d\n", s32Volume);
printf("#Output Path: %s\n", pOutPath);
RK_MPI_SYS_Init();
AI_CHN_ATTR_S ai_attr;
ai_attr.pcAudioNode = pDeviceName;
ai_attr.enSampleFormat = RK_SAMPLE_FMT_S16;
ai_attr.u32NbSamples = u32FrameCnt;
ai_attr.u32SampleRate = u32SampleRate;
ai_attr.u32Channels = u32ChnCnt;
ai_attr.enAiLayout = AI_LAYOUT_NORMAL;
ret = RK_MPI_AI_SetChnAttr(0, &ai_attr);
ret |= RK_MPI_AI_EnableChn(0);
if (ret) {
printf("Enable AI[0] failed! ret=%d\n", ret);
return -1;
}
pthread_t read_thread;
pthread_create(&read_thread, NULL, GetMediaBuffer, pOutPath);
ret = RK_MPI_AI_StartStream(0);
if (ret) {
printf("Start AI failed! ret=%d\n", ret);
return -1;
}
printf("%s initial finish\n", __func__);
signal(SIGINT, sigterm_handler);
while (!quit) {
usleep(500000);
}
printf("%s exit!\n", __func__);
RK_MPI_AI_DisableChn(0);
return 0;
}
到了这里,关于RV1126 音频开发(1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!